Skip to content

refactor(a2a): remove unused context id helpers#6407

Open
anxkhn wants to merge 2 commits into
google:mainfrom
anxkhn:fix/a2a-context-id-roundtrip-separator
Open

refactor(a2a): remove unused context id helpers#6407
anxkhn wants to merge 2 commits into
google:mainfrom
anxkhn:fix/a2a-context-id-roundtrip-separator

Conversation

@anxkhn

@anxkhn anxkhn commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

Please ensure you have read the contribution guide before creating a pull request.

Link to Issue or Description of Change

1. Link to an existing issue (if applicable):

  • N/A (no dedicated issue; the bug is described below per the issue-template structure, as CONTRIBUTING allows for non-doc PRs).

2. Or, if no issue exists, describe the change:

Problem:

The A2A context id codec in src/google/adk/a2a/converters/utils.py is not
invertible when app_name, user_id, or session_id contains the /
separator. _to_a2a_context_id joins [ADK, app_name, user_id, session_id] on
ADK_CONTEXT_ID_SEPARATOR ("/"), and _from_a2a_context_id splits on "/"
and requires exactly four parts, otherwise it returns (None, None, None). So
when any field contains /, the join produces more than four segments and the
inverse silently fails:

from google.adk.a2a.converters.utils import (
    _to_a2a_context_id,
    _from_a2a_context_id,
)

cid = _to_a2a_context_id("app", "user", "projects/p/sessions/s")
print(_from_a2a_context_id(cid))
# expected: ('app', 'user', 'projects/p/sessions/s')
# actual:   (None, None, None)

A returned (None, None, None) means A2A session resolution silently fails for
those ids. Fully-qualified resource paths are a realistic source of embedded
/ (for example resource paths used as a user_id, or an Agent Engine session
path used as a session_id).

The decode path also had a stale docstring that still described the old
ADK$app_name$user_id$session_id format, and an unreachable except ValueError
around str.split (which never raises), which masked the failure mode.

Solution:

Percent-encode each field on encode (quote(field, safe="")) and decode it on
decode (unquote(...)). This is the smallest change that:

  • keeps the exact four-part ADK/<app>/<user>/<session> structure (so the
    existing "too many parts" rejection still holds),
  • is invertible for a separator in ANY field (a bounded split(sep, 3) would
    only fix session_id, not user_id/app_name, and would break the existing
    too-many-parts test),
  • leaves ids without special characters byte-identical to the previous format,
    so there is no breaking change on the wire for the common case.

I also fixed the stale $-format docstring and removed the dead
except ValueError.

Testing Plan

Unit Tests:

  • I have added or updated unit tests for my change.
  • All unit tests pass locally.

Added a parametrized regression test
test_roundtrip_context_id_with_separator_in_ids covering / in session_id,
in user_id, in app_name, and a multi-slash session id. It fails on the
current code (each case returns (None, None, None)) and passes with the fix.
Also updated test_to_a2a_context_id_special_characters to expect the
percent-encoded form (%40 for @).

$ pytest tests/unittests/a2a/converters/test_utils.py -q
24 passed

$ pytest tests/unittests/a2a/ -q
366 passed

pre-commit run --files src/google/adk/a2a/converters/utils.py tests/unittests/a2a/converters/test_utils.py
passes (ruff, isort, pyink, addlicense, ADK compliance checks) with no
reformatting.

Manual End-to-End (E2E) Tests:

This is a self-contained, pure-function correctness fix in the A2A context id
codec with no runtime/UI surface, so it is exercised by the unit tests above
rather than an adk web/runner flow. The snippet in the Problem section is a
minimal manual repro (returns (None, None, None) before the fix, the original
ids after).

Checklist

  • I have read the CONTRIBUTING.md document.
  • I have performed a self-review of my own code.
  • I have commented my code, particularly in hard-to-understand areas.
  • I have added tests that prove my fix is effective or that my feature works.
  • New and existing unit tests pass locally with my changes.
  • I have manually tested my changes end-to-end.
  • Any dependent changes have been merged and published in downstream modules. (N/A)

Additional context

The percent-encode approach was chosen over a bounded left split because it fixes
every field (not just session_id) and preserves the existing four-part
validation (including the "too many parts" rejection test). Ids without special
characters are unchanged on the wire.

@adk-bot adk-bot added the core [Component] This issue is related to the core interface and implementation label Jul 16, 2026
@guglielmo-san

Copy link
Copy Markdown
Member

@anxkhn thanks for the contribution
These two methods are not used anywhere in the codebase, and should be rather removed

@anxkhn anxkhn changed the title fix(a2a): percent-encode context id fields so ids with separators round-trip refactor(a2a): remove unused context id helpers Jul 17, 2026
@anxkhn

anxkhn commented Jul 17, 2026

Copy link
Copy Markdown
Contributor Author

Thanks, agreed. I updated this PR to remove both unused context ID helpers, their constants, and the corresponding tests instead.

@anxkhn
anxkhn force-pushed the fix/a2a-context-id-roundtrip-separator branch from 24d900c to cc96582 Compare July 17, 2026 10:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

core [Component] This issue is related to the core interface and implementation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants