Skip to content

InMemorySessionService allows duplicate events to be appended during concurrent state broadcasts #5723

Description

@chriskinzel

Description

In InMemorySessionService.append_event, there is no deduplication check before appending an Event to session.events. When an orchestrator or background task broadcasts shared state updates to multiple concurrent agent sessions, race conditions can cause the exact same event ID to be appended multiple times to a session's history.

Proposed Solution

Add a simple, universal deduplication check at the beginning of append_event:

async def append_event(self, session: Session, event: Event) -> Event:
    if event.partial:
        return event
    if any(e.id == event.id for e in session.events):
        return event
    # ...

Activity

  1. added
    services[Component] This issue is related to runtime services, e.g. sessions, memory, artifacts, etc
    on May 18, 2026
  2. klateefa commented on May 18, 2026

    @klateefa
    Collaborator

    @chriskinzel A possible resolution would be to add event ID deduplication in append_event(), and potentially add synchronization/locking to avoid concurrent race conditions during appends.
    Could you also confirm which ADK version you're using and whether this still reproduces on the latest release? If not please use latest version of ADK and also share more details to help us work on this.
    Thanks!

  3. surajksharma07 commented on May 29, 2026

    @surajksharma07
    Collaborator

    @chriskinzel Thanks for the detailed report and for linking PR #5727 — looks like this caught some good community traction, with he-yufeng's PR #5743 and devteamaegis's PR #5815 (which already has a committed fix) both targeting the same append_event deduplication gap.

    Since the fix is actively being tracked across those PRs and we haven't heard back in 2 weeks since @klateefa's question about your ADK version, going ahead and closing this out — the bug itself is being handled on the PR side.

    Keep an eye on PR #5815 for the merge; once that lands, the deduplication check will be in the main branch.

    Feel free to reopen if there's additional context you wanted to share or if the merged fix doesn't fully cover your concurrent broadcast scenario!

  4. added a commit that references this issue on Aug 14, 2026
    4d74774
  5. DeanChensj commented on Oct 8, 2026

    @DeanChensj
    Collaborator

    Following up after an architectural review of ADK's session lifecycle:

    ADK does not broadcast the same Event instance (or duplicate event.id) across multiple concurrent Session references for the same session_id:

    • Within a single invocation (including ParallelAgent and parallel workflow branches), all branches share one InvocationContext.session object and serialize append_event calls through the runner's event queue.
    • Across separate invocations, concurrent writes from stale Session snapshots are rejected with StaleSessionError on persistent backends (DatabaseSessionService, SqliteSessionService, FirestoreSessionService), and duplicate event.id values violate storage uniqueness constraints.
    • To share state across concurrent sessions, use app: or user: scoped state keys (State.APP_PREFIX / State.USER_PREFIX), and call get_session() when a fresh session snapshot is needed.

    Marking this issue as not_planned for clarity so future contributors are not misled by the concurrent-broadcast premise.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

request clarification[Status] The maintainer need clarification or more information from the authorservices[Component] This issue is related to runtime services, e.g. sessions, memory, artifacts, etc

Type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions