Skip to content

fix(adk): pass user_id as query param in create_session to fix SessionNotFoundError#1913

Merged
EItanya merged 2 commits into
kagent-dev:mainfrom
Abhiram-Rakesh:fix/session-create-user-id-query-param
May 26, 2026
Merged

fix(adk): pass user_id as query param in create_session to fix SessionNotFoundError#1913
EItanya merged 2 commits into
kagent-dev:mainfrom
Abhiram-Rakesh:fix/session-create-user-id-query-param

Conversation

@Abhiram-Rakesh

Copy link
Copy Markdown
Contributor

Summary

Fixes #1882

POST /api/sessions was the only KAgentSessionService method that did not include user_id as a query parameter. The controller's UnsecureAuthenticator resolves the caller's identity from the query param (or X-User-Id header), not the JSON body:

// go/core/internal/httpserver/auth/authn.go — UnsecureAuthenticator
userID := query.Get("user_id")       // reads query param
if userID == "" {
    userID = reqHeaders.Get("X-User-Id")
}
if userID == "" {
    userID = "admin@kagent.dev"      // fallback when neither is set
}

Because the user_id was only in the JSON body, the create call fell back to "admin@kagent.dev" while every subsequent get_session / append_event call used the A2A-derived user_id (e.g. "A2A_USER_<contextId>"). The guaranteed mismatch caused a 404 on the follow-up GET, which surfaced as SessionNotFoundError in google.adk.runners.

Root cause trace

step call user_id used result
1 GET /api/sessions/<CTX>?user_id=A2A_USER_<CTX> A2A_USER_<CTX> 404 — not yet created
2 POST /api/sessions (body only, no query param) admin@kagent.dev ← fallback 201 — session created under wrong identity
3 GET /api/sessions/<CTX>?user_id=A2A_USER_<CTX> A2A_USER_<CTX> 404 — exists but under admin@kagent.dev
4 SessionNotFoundError

Fix

Add ?user_id={user_id} to the POST /api/sessions URL in create_session, consistent with every other method in the same class:

  • get_sessionf"/api/sessions/{session_id}?user_id={user_id}&..."
  • list_sessionsf"/api/sessions?user_id={user_id}"
  • delete_sessionf"/api/sessions/{session_id}?user_id={user_id}"
  • append_eventf"/api/sessions/{session.id}/events?user_id={session.user_id}"
  • create_session"/api/sessions" ❌ → f"/api/sessions?user_id={user_id}" ✅ (this PR)

Test

Added test_create_session_passes_user_id_as_query_param to test_session_service.py — asserts that the URL passed to client.post contains user_id=<value> as a query param. This is a regression test so the mismatch cannot silently reappear.

Notes

  • Reproducible on every A2A message/send invocation with controller.auth.mode: unsecure (the default in-cluster setup)
  • PR fix: ensure user identity is propagated across A2A requests/sessions #1775 fixed the authenticated path (call_context.user.user_name); this PR fixes the unauthenticated fallback path
  • Verified against UnsecureAuthenticator source in go/core/internal/httpserver/auth/authn.go

Copilot AI review requested due to automatic review settings May 25, 2026 07:14
@github-actions github-actions Bot added the bug Something isn't working label May 25, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

Adds a regression fix ensuring user_id is consistently sent as a query parameter when creating sessions, preventing mismatched identities that can lead to SessionNotFoundError.

Changes:

  • Update KAgentSessionService.create_session() to include user_id in the POST /api/sessions query string.
  • Add an async unit test verifying user_id is present in the create-session request URL.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
python/packages/kagent-adk/src/kagent/adk/_session_service.py Includes user_id as a query parameter when creating a session to align with controller auth behavior.
python/packages/kagent-adk/tests/unittests/test_session_service.py Adds a regression test asserting the create-session request includes user_id in the URL.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

# while all lookups use the A2A-derived user_id, causing SessionNotFoundError.
response = await self.client.post(
"/api/sessions",
f"/api/sessions?user_id={user_id}",

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in the latest push — switched to params={"user_id": user_id} so httpx handles the URL encoding correctly.

Comment on lines +91 to +97
client.post.assert_called_once()
call_url = client.post.call_args[0][0]
assert "user_id=A2A_USER_ctx123" in call_url, (
f"Expected 'user_id=A2A_USER_ctx123' in POST URL, got: {call_url!r}. "
"Without this query param the controller's UnsecureAuthenticator falls back "
"to 'admin@kagent.dev', causing a SessionNotFoundError on subsequent lookups."
)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in the latest push — the assertion now checks client.post.call_args.kwargs["params"]["user_id"] directly, so it's robust to URL encoding and argument ordering changes.

…nNotFoundError

POST /api/sessions was the only KAgentSessionService method that did not
include user_id as a query parameter. The controller's UnsecureAuthenticator
resolves the caller's identity from the query param (or X-User-Id header),
not the JSON body, so the create call fell back to "admin@kagent.dev" while
every subsequent get_session / append_event call used the A2A-derived user_id
(e.g. "A2A_USER_<contextId>"). The guaranteed mismatch caused a 404 on the
follow-up GET, which surfaced as SessionNotFoundError in google.adk.runners.

All other methods (get_session, list_sessions, delete_session, append_event)
already pass ?user_id=... correctly. Aligns create_session to match, using
httpx params= dict to ensure correct URL encoding.

Fixes kagent-dev#1882

Signed-off-by: Abhiram-Rakesh <abhidevops096@gmail.com>
@Abhiram-Rakesh Abhiram-Rakesh force-pushed the fix/session-create-user-id-query-param branch from b842633 to 5735bab Compare May 25, 2026 07:40
@EItanya EItanya merged commit 067c2fa into kagent-dev:main May 26, 2026
23 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

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

4 participants