Skip to content

fix(claude-sdk-oauth): never resume an SDK session id that init never confirmed - #1318

Merged
code-yeongyu merged 4 commits into
mainfrom
fix/claude-sdk-oauth-unconfirmed-binding
Sep 3, 2026
Merged

fix(claude-sdk-oauth): never resume an SDK session id that init never confirmed#1318
code-yeongyu merged 4 commits into
mainfrom
fix/claude-sdk-oauth-unconfirmed-binding

Conversation

@code-yeongyu

@code-yeongyu code-yeongyu commented Sep 3, 2026

Copy link
Copy Markdown
Owner

Summary

After a failed cold seed, claude-sdk-oauth kept a continuity binding whose SDK session id had only ever been minted locally. The next turn chose reattach, Claude Code answered No conversation found with session ID: <id>, and every later turn repeated the cycle with zero usage (oh-my-openagent#7562). A session id is now resumable only once Claude Code acknowledged it, and an id Claude Code reports missing is dropped instead of retried.

Changes

  • Acknowledgement tracking (session-registry.ts, session-registry-pump.ts): resident entries carry sdkSessionIdConfirmed; entries created from a resume start confirmed, locally minted ids start unconfirmed, and both a system/init message and the replay echo that claims the turn confirm the id.
  • Continuity decision (session-reattach.ts, session-continuity.ts, session-observability.ts): bindings carry the flag; withoutUnconfirmedResume turns a reattach/fork on an unconfirmed binding into flatten with the new reason session_unconfirmed. Same-turn retry checkpoints (timeout_retry, Retry after provider stream-start timeout re-bills the full conversation (cache_control dropped / breakpoints moved) — measured 5.7x cost #723) are untouched because they never resume the id.
  • Dead ids (session-turn-attempt.ts): an attempt whose failure names No conversation found with session ID forgets the binding outright.
  • AGENTS.md invariant list, changes.md entry, CHANGELOG bullet.

QA & Evidence

Evidence dir: sisyphuslabs/.omo/evidence/ulw/claude-sdk-fable51-20260903/ (all runs on bunshin mengmotaMac, never local).

  • RED (g7-red.log): the #7562 repro (is_error result before init/replay) left a resumable binding with the unconfirmed id.
  • GREEN (laneE-orch-green2.log): claude-sdk-oauth-unconfirmed-binding.test.ts 6/6 plus observability, Retry after provider stream-start timeout re-bills the full conversation (cache_control dropped / breakpoints moved) — measured 5.7x cost #723 retry continuity, continuity-decision, pump, session-registry and reattach suites: 7 files / 74 tests.
  • Mutation (g7-mutation-orchestrator.log, run by the orchestrator): removing the unconfirmed guard, the dead-id forget, or the claim confirmation each fails exactly one test.
  • Regression (g7-regression-orchestrator.log): tsc --noEmit -p tsconfig.build.json + biome + full claude-sdk-oauth cluster: 485 passed / 3 skipped at 27e5f55 (before rebase).

Risks & Residuals

Related Issues

@code-yeongyu
code-yeongyu force-pushed the fix/claude-sdk-oauth-unconfirmed-binding branch from 27e5f55 to d4ed57d Compare September 3, 2026 04:38
code-yeongyu and others added 3 commits September 3, 2026 14:02
…nfirms the session id

Ultraworked with [omo](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: sisyphus-dev-ai <sisyphus-dev-ai@users.noreply.github.com>
…and drop ids Claude Code reports missing

The first cut forgot every binding an unconfirmed entry published, which also
erased the same-turn retry checkpoints #723 relies on. Carry the confirmation
on the binding instead: init or the replay echo confirms the id, an unconfirmed
binding may still drive a byte-identical same-turn re-seed but never a resume
or fork (new continuity reason session_unconfirmed), and a failure that names
'No conversation found with session ID' forgets the binding outright.
…rd and report session_unconfirmed

The retained-attempt wrapper calls discard() after a failed attempt, which
re-published the checkpoint of an id Claude Code had just declared missing;
discard now forgets it instead. session_unconfirmed joins the sanitized
continuity reasons so observations and telemetry keep the attribution instead
of downgrading it to other.
@code-yeongyu
code-yeongyu force-pushed the fix/claude-sdk-oauth-unconfirmed-binding branch from 51365a7 to b0adf44 Compare September 3, 2026 05:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Regression]: claude-sdk-oauth as OMO main model loops on replay/missing conversation IDs in resumed sessions

1 participant