Skip to main content

Google ADK DatabaseSessionService: "TypeError: fromisoformat: argument must be str" on SQLite

get_session() fails when a SQLite session table holds float timestamps. Why it happens, how to reproduce it, and the version that handles it.

Updated 6 min readMarkdown

Disclosure: I work on MemorySync (I'm Mohammed, the founder). I drafted this page with AI assistance and checked it against the GitHub issue, the fix commit and the ADK source listed under Sources on Nov 11, 2026. Code status: I ran the repro offline on google-adk 2.3.0 (SQLAlchemy 2.0.41) and google-adk 2.14.0 (SQLAlchemy 2.1.8) with sqlite+aiosqlite, Python 3.13, no agent and no model. To get a float into the table I wrote it directly with Python's sqlite3; I didn't run SqliteSessionService, adk web or adk api_server against the same file, or any MemorySync code.

You use ADK's DatabaseSessionService with a SQLite URL, and reading a session back fails:

TypeError: fromisoformat: argument must be str

The traceback ends inside SQLAlchemy's str_to_datetime. That's google/adk-python issue #6352, "DatabaseSessionService.get_session() raises TypeError: fromisoformat: argument must be str", reported on google-adk 2.3.0.

MemorySync doesn't fix this bug. It's in how ADK's SQL session store reads timestamps, and you need the fix below with or without MemorySync.

Skip the memory plumbing around this fix. Sessions are ADK's short-term store. Once they read back cleanly, the MemorySync Google ADK guide shows a BaseMemoryService for memory that lasts across sessions. It doesn't replace your session service. When you're ready, see MemorySync. Founding offer: use code FOUNDING30 for 30% off Starter for your first 3 months (Settings → Billing).

Status (Nov 11, 2026)

  • #6352 was opened Jul 9, 2026 and closed as completed on Jul 16, 2026 by commit 2da09e6 ("fix: handle sqlite float timestamps in PreciseTimestamp", merging PR #6355).
  • GitHub's compare view shows that commit included in the v2.5.0 and v2.6.0 tags. I ran 2.14.0 (the latest on PyPI on Nov 11, 2026), and it reads the same file without error.

Why it happens

From the issue thread: ADK's SQL schema stores timestamps in a PreciseTimestamp column backed by SQLAlchemy DateTime. On SQLite, SQLAlchemy expects those values as text and parses them with fromisoformat. If a row holds a REAL (a Unix epoch float), the parser gets a float and raises.

How does a float get there? The thread's leading explanation, which the reporter confirmed, is a second writer: ADK's other SQLite backend, SqliteSessionService, stores timestamps as raw floats. If it and DatabaseSessionService touch the same database file, the SQL service can't read what the other one wrote. A maintainer also noted in the thread: "if SQLite is your main database we recommend just use the SqliteSessionService."

Step 1: Reproduce it

This creates a session with DatabaseSessionService, puts a float in the update_time column (standing in for the other writer), then reads the session back with a fresh service:

import asyncio, os, sqlite3, time
from google.adk.sessions import DatabaseSessionService

DB = "/tmp/adk_repro.db"
if os.path.exists(DB):
    os.remove(DB)

async def main():
    svc = DatabaseSessionService(db_url=f"sqlite+aiosqlite:///{DB}")
    await svc.create_session(app_name="app", user_id="u1", session_id="s1")

    con = sqlite3.connect(DB)
    con.execute("update sessions set update_time=? where id='s1'", (time.time(),))
    con.commit()
    con.close()

    svc2 = DatabaseSessionService(db_url=f"sqlite+aiosqlite:///{DB}")
    try:
        s = await svc2.get_session(app_name="app", user_id="u1", session_id="s1")
        print("OK", s.last_update_time)
    except Exception as e:
        print("FAILED", type(e).__name__, e)

asyncio.run(main())

You need the db extra: pip install "google-adk[db]" plus aiosqlite. What I got:

google-adk 2.3.0, SQLAlchemy 2.0.41:  FAILED TypeError fromisoformat: argument must be str
google-adk 2.14.0, SQLAlchemy 2.1.8:  OK 1794409299.836908

Step 2: Upgrade ADK

The fix overrides result_processor on PreciseTimestamp so a float is converted to a datetime before SQLAlchemy's text parser sees it. The thread explains why process_result_value alone wasn't enough: the base DateTime processor runs first and fails on the float.

pip install -U "google-adk[db]"

Then check that result_processor is defined in google/adk/sessions/schemas/shared.py in your installed package if you want to be sure you have the fix.

Step 3: Use one session backend per database file

Upgrading stops the crash, but two services writing different timestamp formats into one file is still worth fixing:

  • SQLite only: use SqliteSessionService, as the maintainer suggested, and point nothing else at that file.
  • Postgres, MySQL or another SQL database: use DatabaseSessionService, and give it its own database.
  • adk web and adk api_server: per a comment in the thread, both fall back to the same per-agent SQLite session store unless you pass --session_service_uri. If you pass it to one process and not the other, they can end up on different stores. Pass the same value to both.

Skip the plumbing with MemorySync

Disclosure: I build MemorySync.

This doesn't change the fix above: DatabaseSessionService is still your session store, so upgrade it as in Step 2. The MemorySync Google ADK guide documents MemorySyncMemoryService, an ADK BaseMemoryService you pass as Runner(memory_service=...) next to whatever session_service you use. You call add_session_to_memory(session) after a conversation, and ADK's preload_memory tool brings that user's memories into later sessions. It requires google-adk 2.0+ and Python 3.10+ and lists google-adk-memorysync 1.1.0.

From the guide:

Unverified (not run):

pip install google-adk-memorysync google-adk
from google.adk.runners import Runner
from google_adk_memorysync import MemorySyncMemoryService

memory_service = MemorySyncMemoryService()  # reads MEMORYSYNC_API_KEY

runner = Runner(
    agent=agent,
    app_name="support",
    session_service=session_service,  # your DatabaseSessionService
    memory_service=memory_service,
)

# after a conversation:
session = await runner.session_service.get_session(
    app_name="support", user_id="customer-7", session_id="thread-42"
)
await memory_service.add_session_to_memory(session)

Snippet adapted from the MemorySync Google ADK guide, which uses InMemorySessionService; I swapped in your session service and haven't run it for this page.

Try it: MemorySync is optional here: the steps above work without it. If you want the memory layer from the snippet, see MemorySync, create an API key in the dashboard and drop the snippet into your agent.

FAQ

I deleted the database and it still fails. Why? The reporter saw the same thing. A fresh file only helps if nothing else writes floats into it; check every process and service that uses that path.

Do I lose sessions by switching service? The two services use different schemas, so don't point a new service at the old file and expect it to read everything. Plan a migration or start a new file.

Is this a SQLAlchemy bug? No. SQLAlchemy is doing what a DateTime column on SQLite does. The fix is on ADK's side, in PreciseTimestamp.

Sources

  • github.com/google/adk-python/issues/6352 (opened 2026-07-09, closed as completed 2026-07-16, 11 comments; root cause, SqliteSessionService float timestamps, maintainer recommendation, --session_service_uri note; read 2026-10-30)
  • Commit 2da09e60d7d03d27bf9aa721db37cf0475157c21, "fix: handle sqlite float timestamps in PreciseTimestamp" (PR #6355), and GitHub compare against v2.5.0 and v2.6.0 (read 2026-10-30)
  • google-adk 2.14.0 source: google/adk/sessions/schemas/shared.py (read 2026-11-11)
  • Offline runs on google-adk 2.3.0 and 2.14.0, Python 3.13 (2026-11-11)
  • MemorySync Google ADK guide: docs.memorysync.io/guides/google-adk (fetched 2026-10-30)

Try it

For an overview of MemorySync, see the MemorySync homepage.

Next step: read the MemorySync Google ADK guide, then see MemorySync. Founding offer: use code FOUNDING30 for 30% off Starter for your first 3 months (Settings → Billing).

About the author

  • Building MemorySync (memorysync.io) — persistent memory infrastructure for AI agents, Cursor, and Claude Code.

No comments yet. Be the first to comment.