Skip to content

Declarative agent A2A: SessionNotFoundError due to user_id mismatch between session-create and session-get #1882

@davidkarlsen

Description

@davidkarlsen

Summary

Inbound A2A message/send to a Declarative ADK agent fails with
SessionNotFoundError. kagent-adk._agent_executor creates the session
through kagent-controller's API under one user_id, but
google.adk.runners._get_or_create_session then looks the same session
up under a different user_id, so the GET 404s and execution aborts.

Environment

  • kagent v0.9.4 (chart + bundled kagent-adk)
  • Agent CR: type: Declarative, ADK runtime, A2A enabled
  • controller.auth.mode: unsecure

Repro

Any A2A request to a Declarative agent over its operator-managed A2A
Service. Inbound JSON-RPC envelope carries a non-empty context_id.

Trace (sanitized — log lines reformatted, no internal IDs)

step call result user_id used
1 GET /api/sessions/?... 404 A2A_USER_
2 POST /api/tasks 201 (auth-derived)
3 POST /api/sessions 201 (auth-derived)
4 POST /api/tasks 201 (auth-derived)
5 POST /api/sessions//events?user_id= 201 ← different
6 GET /api/sessions/?... 404 A2A_USER_ ← mismatch
7 SessionNotFoundError: Session not found:

<CTX> = the inbound A2A request's context_id.
<AUTH> = the user_id injected by the controller's auth layer
(in unsecure mode this is the controller's static fallback identity).

Python traceback terminates in:

google/adk/runners.py:435  _get_or_create_session
  → google.adk.errors.session_not_found_error.SessionNotFoundError

Root-cause hypothesis

  • The A2A executor derives a synthetic A2A_USER_<context_id> and uses
    it for session GETs.
  • Session creation (POST /api/sessions, POST /api/sessions/<CTX>/events)
    writes under the controller's auth-derived identity instead.
  • The two keyspaces don't overlap, so the lookup never finds the session
    it just created.

Expected

A single user_id consistently used for both create and lookup, so the
follow-up GET resolves.

Notes

  • The [EXPERIMENTAL] ResumabilityConfig UserWarning printed at startup
    is co-located but benign.
  • Reproducible on every A2A invocation; not flaky.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    Status

    Backlog

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions