fix(adk): pass user_id as query param in create_session to fix SessionNotFoundError#1913
Conversation
There was a problem hiding this comment.
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 includeuser_idin the POST/api/sessionsquery string. - Add an async unit test verifying
user_idis 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}", |
There was a problem hiding this comment.
Fixed in the latest push — switched to params={"user_id": user_id} so httpx handles the URL encoding correctly.
| 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." | ||
| ) |
There was a problem hiding this comment.
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>
b842633 to
5735bab
Compare
Summary
Fixes #1882
POST /api/sessionswas the onlyKAgentSessionServicemethod that did not includeuser_idas a query parameter. The controller'sUnsecureAuthenticatorresolves the caller's identity from the query param (orX-User-Idheader), not the JSON body:Because the
user_idwas only in the JSON body, the create call fell back to"admin@kagent.dev"while every subsequentget_session/append_eventcall used the A2A-derived user_id (e.g."A2A_USER_<contextId>"). The guaranteed mismatch caused a 404 on the follow-up GET, which surfaced asSessionNotFoundErroringoogle.adk.runners.Root cause trace
GET /api/sessions/<CTX>?user_id=A2A_USER_<CTX>A2A_USER_<CTX>POST /api/sessions(body only, no query param)admin@kagent.dev← fallbackGET /api/sessions/<CTX>?user_id=A2A_USER_<CTX>A2A_USER_<CTX>admin@kagent.devSessionNotFoundErrorFix
Add
?user_id={user_id}to thePOST /api/sessionsURL increate_session, consistent with every other method in the same class:get_session→f"/api/sessions/{session_id}?user_id={user_id}&..."✅list_sessions→f"/api/sessions?user_id={user_id}"✅delete_session→f"/api/sessions/{session_id}?user_id={user_id}"✅append_event→f"/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_paramtotest_session_service.py— asserts that the URL passed toclient.postcontainsuser_id=<value>as a query param. This is a regression test so the mismatch cannot silently reappear.Notes
message/sendinvocation withcontroller.auth.mode: unsecure(the default in-cluster setup)call_context.user.user_name); this PR fixes the unauthenticated fallback pathUnsecureAuthenticatorsource ingo/core/internal/httpserver/auth/authn.go