Skip to content

A Workflow resumed from DatabaseSessionService passes bytes on as base64 text #7852

Closed

Description

@RyanLin5967

Describe the Bug:

Currently, a resumed Workflow replays each finished node's output from the JSON DatabaseSessionService stored, so a node that runs after the pause and takes bytes gets the base64 text as bytes. Without the pause, or with InMemorySessionService, it gets the original bytes.

Steps to Reproduce:

pip install "google-adk[db]==2.13.0", then run:

import asyncio
from google.adk import Workflow
from google.adk.runners import Runner
from google.adk.sessions import DatabaseSessionService
from google.adk.workflow import node
from google.genai import types

def produce():
    return b"\x00\x01"

def consume(node_input: bytes):
    print(node_input)

async def main():
    svc = DatabaseSessionService("sqlite+aiosqlite:///t.db")
    wf = Workflow(name="wf", edges=[("START", produce, node(consume, require_confirmation=True))])
    runner = Runner(app_name="app", node=wf, session_service=svc)
    s = await svc.create_session(app_name="app", user_id="u")
    async def send(part):
        msg = types.UserContent(part)
        return [c async for e in runner.run_async(user_id="u", session_id=s.id, new_message=msg)
                for c in e.get_function_calls()]
    calls = await send(types.Part(text="go"))
    ok = types.FunctionResponse(id=calls[-1].id, name=calls[-1].name, response={"confirmed": True})
    await send(types.Part(function_response=ok))

asyncio.run(main())
# b'AAE=', should be b'\x00\x01'
# 'AAE=' is b'\x00\x01' in base64, the text the stored session event holds for produce's output

SqliteSessionService, which adk web uses by default, gives b'AAE=' too, and so does a pydantic model's bytes field.

Expected Behavior:

consume prints b'\x00\x01', the bytes produce returned.

Observed Behavior:

consume prints b'AAE=', and nothing raises.

Environment Details:

  • ADK Library Version (pip show google-adk): 2.13.0 and main
  • Desktop OS: macOS 26.7.1, arm64 (Darwin 25.6.0)
  • Python Version (python -V): Python 3.12.16

Model Information:

  • Are you using LiteLLM: No
  • Which model is being used: N/A

Additional Context:

StorageEvent.from_event stores the event with model_dump(mode="json"), so Event's ser_json_bytes='base64' writes the bytes as text. On resume check_interception replays that text as produce's output, and _process_rehydrated_output passes anything but types.Content through unchanged.

How often has this issue occurred?:

  • Always (100%)

Activity

  1. adk-bot commented on Oct 30, 2026

    @adk-bot
    Collaborator

    Resolved by #7853 (imported and merged in commit 81c3fe6). Closing issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions