You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
A Workflow resumed from DatabaseSessionService passes bytes on as base64 text #7852
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:
importasynciofromgoogle.adkimportWorkflowfromgoogle.adk.runnersimportRunnerfromgoogle.adk.sessionsimportDatabaseSessionServicefromgoogle.adk.workflowimportnodefromgoogle.genaiimporttypesdefproduce():
returnb"\x00\x01"defconsume(node_input: bytes):
print(node_input)
asyncdefmain():
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=awaitsvc.create_session(app_name="app", user_id="u")
asyncdefsend(part):
msg=types.UserContent(part)
return [casyncforeinrunner.run_async(user_id="u", session_id=s.id, new_message=msg)
forcine.get_function_calls()]
calls=awaitsend(types.Part(text="go"))
ok=types.FunctionResponse(id=calls[-1].id, name=calls[-1].name, response={"confirmed": True})
awaitsend(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.
Activity
fix: decode base64 bytes in rehydrated workflow node outputs
adk-bot commentedon Oct 30, 2026
Resolved by #7853 (imported and merged in commit 81c3fe6). Closing issue.