Skip to content

claude-cli session binding invalidated on nearly every reply turn (reuse=invalidated:system-prompt) #99372

Description

@obviyus

What happened

On a production deployment tracking latest main (Telegram group, claude-cli backend), nearly every reply turn discards the stored CLI session binding and starts a fresh CLI session with history replay:

cli session reset: provider=claude-cli reason=system-prompt
cli exec: … trigger=user useResume=false session=none resumeSession=none reuse=invalidated:system-prompt historyPrompt=present

Observed alternation over one hour of group traffic:

  • primary reply turns: reuse=invalidated:system-prompt, historyPrompt=present
  • coalesced/followup turns seconds later: session=none reuse=none historyPrompt=none
  • heartbeat turns: reuse=reusable, resume works
  • occasionally two user turns 15s apart do reuse (reuse=reusable), so the hash inputs are not purely per-turn volatile — different reply execution paths appear to write incompatible bindings.

Impact

CLI resume is effectively dead for interactive turns: every turn pays full history replay in fresh context (no provider-side prompt cache reuse), and transcript continuity inside the CLI harness is lost. This defeats the append-only/cache-hit design of the session transcript.

Where to look

resolveCliSessionReuse (src/agents/cli-session.ts) invalidates with reason system-prompt when any of extraSystemPromptHash, messageToolPolicyHash, or promptToolNamesHash differs from the stored binding. Those inputs are assembled in src/agents/cli-runner/prepare.ts (extraSystemPromptStatic fast-path at ~line 352, messageToolPolicyHash at ~line 358) and fed differently by the primary reply path (get-reply-run.ts), the followup/queue path (followup-runner.ts, queue/drain.ts), and heartbeats.

Expected

Binding-reuse hash inputs must be session-stable facts, resolved identically for every trigger and execution path of the same session. Per-message metadata must never reach them; policy facts (sourceReplyDeliveryMode, requireExplicitMessageTarget, prompt tool names) must not flap between primary/followup/heartbeat flavors. Fix at the parameter-assembly owner; do not loosen the reuse comparison itself (stale-system-prompt invalidation must keep working).

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    P1High-priority user-facing bug, regression, or broken workflow.bugSomething isn't workingimpact:session-stateSession, memory, transcript, context, or agent state can drift or corrupt.

    Type

    No type

    Fields

    Priority

    None yet

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions