[BUG] Session unrecoverable after upstream 429: every retry returns 400 previous_message_id
Preflight Checklist
- [x] I have searched existing issues and this hasn't been reported yet
- [x] This is a single bug report (please file separate reports for different bugs)
- [x] I am using the latest version of Claude Code
What's Wrong?
When the Anthropic API returns a transient server-side rate-limit (Server is),
temporarily limiting requests (not your usage limit) · Rate limited
Claude Code's subsequent retry attempts fail permanently with:
API Error: 400 diagnostics.previous_message_id: must be the id from a prior
/v1/messages response (starts with msg_)
Every user-initiated retry (continue, resume, free-text prompts, even
/something) returns the same 400. The session becomes unrecoverable; the
only escape is /exit and starting fresh, which loses in-session state.
What Should Happen?
the session should resume after API rate limiting expired
Error Messages/Logs
pass. Thanks for the standard + sweep verdict, made shipping #68 straightforward.
⎿ API Error: Server is temporarily limiting requests (not your usage limit) · Rate limited
✻ Crunched for 3s · 4 shells still running
❯ continue
⎿ API Error: 400 diagnostics.previous_message_id: must be the `id` from a prior /v1/messages response (starts with
`msg_`)
✻ Churned for 0s · 4 shells still running
❯ continue
⎿ API Error: 400 diagnostics.previous_message_id: must be the `id` from a prior /v1/messages response (starts with
`msg_`)
✻ Churned for 0s · 4 shells still running
❯ continue
⎿ API Error: 400 diagnostics.previous_message_id: must be the `id` from a prior /v1/messages response (starts with
`msg_`)
✻ Crunched for 1s · 4 shells still running
❯ resume
⎿ API Error: 400 diagnostics.previous_message_id: must be the `id` from a prior /v1/messages response (starts with
`msg_`)
✻ Worked for 0s · 4 shells still running
❯ what is wrong?
⎿ API Error: 400 diagnostics.previous_message_id: must be the `id` from a prior /v1/messages response (starts with
`msg_`)
✻ Worked for 0s · 4 shells still running
❯ check out the history
⎿ API Error: 400 diagnostics.previous_message_id: must be the `id` from a prior /v1/messages response (starts with
`msg_`)
✻ Sautéed for 0s · 4 shells still running
Steps to Reproduce
- Hold a long-running interactive session.
- Issue a prompt that the API throttles with the "Server is temporarily
limiting requests (not your usage limit)" 429 (we hit it under normal
foreground use — no abuse, no usage cap).
- Observe the assistant turn does not complete.
- Type anything to retry.
Claude Model
Opus
Is this a regression?
I don't know
Last Working Version
_No response_
Claude Code Version
2.1.81
Platform
Anthropic API
Operating System
Ubuntu/Debian Linux
Terminal/Shell
Other
Additional Information
claude write-up
Title
Session unrecoverable after upstream 429: every retry returns 400 previous_message_id
Body
## Summary
When the Anthropic API returns a transient server-side rate-limit (Server is),
temporarily limiting requests (not your usage limit) · Rate limited
Claude Code's subsequent retry attempts fail permanently with:
API Error: 400 diagnostics.previous_message_id: must be the id from a prior
/v1/messages response (starts with msg_)
Every user-initiated retry (continue, resume, free-text prompts, even
/something) returns the same 400. The session becomes unrecoverable; the
only escape is /exit and starting fresh, which loses in-session state.
## Reproduction
- Hold a long-running interactive session.
- Issue a prompt that the API throttles with the "Server is temporarily
limiting requests (not your usage limit)" 429 (we hit it under normal
foreground use — no abuse, no usage cap).
- Observe the assistant turn does not complete.
- Type anything to retry.
Expected: client retries with the last valid previous_message_id (or no
previous_message_id if the failed turn was never persisted server-side),
the next call succeeds once the throttle clears.
Actual: every subsequent request includes a previous_message_id the API
doesn't recognize and returns a 400. The state never self-heals, regardless
of how long the user waits.
## Hypothesis
The client appears to advance its previous_message_id pointer optimistically
based on the request it sent, not based on a successful response containing
a real msg_… id. When the request fails before producing an assistant
message id, the pointer is left referencing something the server never
issued, and all subsequent calls are rejected.
## Severity
Medium: the workaround (/exit, lose context) is reliable but expensive —
in our setup the session held substantial in-flight context and
inter-agent state. The bug turns a transient server-side blip into a
permanent loss of the session.
## Version
(fill in: output of claude --version and OS — Linux 6.17.0 / Ubuntu in
my case)
## Full transcript of the failure mode
[Paste the literal terminal output from the failed session — the
"continue / resume / what is wrong? / check out the history" sequence
that all returned the same 400.]
This issue has 8 comments on GitHub. Read the full discussion on GitHub ↗