Skip to content

fix(claude): recover failed turns and show native limit notices - #6

Draft
q1 wants to merge 2 commits into
sync/20260906T212712Zfrom
fix/claude-failed-turn-recovery
Draft

fix(claude): recover failed turns and show native limit notices#6
q1 wants to merge 2 commits into
sync/20260906T212712Zfrom
fix/claude-failed-turn-recovery

Conversation

@q1

@q1 q1 commented Sep 6, 2026

Copy link
Copy Markdown
Owner

After a Claude usage-limit failure, unchanged Continue messages can keep failing even after the account is changed externally and new threads work. Changing only effort appears to fix the model, but actually causes T3 to restart the Claude SDK query and resume the same conversation.

The server now resumes an idle Claude session with a recorded turn failure in a fresh runtime on the next explicit turn. It preserves the conversation cursor, provider instance, workspace, runtime mode, model, and options. It does not automatically resend work, change models, or restart a healthy session or an active turn. The SwiftUI client now renders runtime warnings and the actual payload.message for errors across initial history, pagination, and live updates.

Evidence and scope:

  • Native Claude 2.1.263 emitted new failures for the retries: subtype: success, is_error: true, terminal_reason: api_error, and api_error_status: 429. The adapter correctly failed the turns but left the process ready with lastError, and the reactor reused it.
  • The unchanged retries repeated the same quota snapshot and reported zero API duration and token usage. Those fields alone do not prove that no HTTP request occurred.
  • The successful effort change used the same Fable 5.1 API model and conversation ID, with a new SDK process. The reasoning change was a runtime lifecycle boundary.
  • Claude supports detecting externally changed credentials. This is a T3 recovery fix, not a claim that ordinary credential changes require restarting Claude. The exact internal Claude state responsible for this incident has not been reproduced independently.
  • SwiftUI sent ordinary thread.turn.start commands, omitting modelSelection on unchanged retries. It was not replaying a prior error. Its transcript mapper dropped runtime.warning and ignored payload.message, explaining the missing initial limit notice and generic Runtime error rows.

Validation:

  • 164 focused Claude adapter/reactor tests passed on this branch and on a separate clean upstream-based branch.
  • Against the original reactor, the three failed-session retry regressions fail; healthy, active, and other-provider controls pass.
  • Server typecheck, targeted lint, and whitespace checks passed. The isolated upstream candidate passed the fork-leak check.
  • SwiftUI arm64 build-for-testing passed, including four new runtime-notice tests. The Swift tests were compiled, not executed; no Simulator UI was launched or screenshot verification performed, as requested by the maintainer.

Review structure:

  • Stacked on sync/20260906T212712Z; review the prerequisite sync separately.
  • The first commit is the portable server fix (Upstream: candidate); the second is SwiftUI-only. The server commit applies cleanly to upstream ea646c083 and was tested there. Nothing was submitted upstream.
  • No deployment or live-thread mutation. Manual account-switch/retry validation remains before merge.
  • The full-series seam checker currently counts the three upstream-candidate files as fork seams (42/40) and demands a marker on the reactor. The candidate deliberately has no fork markers so it remains portable; this bookkeeping gate must be reconciled before promotion. The prerequisite sync itself passes its seam gate.

Model: GPT-6. Harness: Codex.

q1 added 2 commits September 6, 2026 15:09
Restart idle Claude runtimes with a recorded turn failure on the next explicit turn while retaining the resume cursor and model options. Cover unchanged retries and the native terminal 429 result shape.

Fork-Feature: base

Upstream: candidate
Keep runtime warnings visible in loaded history and live transcript updates. Render the provider message instead of only the generic runtime error summary.

Fork-Feature: swift-ios

Upstream: no
@q1
q1 force-pushed the sync/20260906T212712Z branch from 0b4924a to db595e1 Compare September 6, 2026 22:09
@q1
q1 force-pushed the fix/claude-failed-turn-recovery branch from caa718e to fcd986d Compare September 6, 2026 22:09
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.

1 participant