microsoft / microsoft/amplifier

Session resume fails with HTTP 400 when crash leaves orphaned tool call followed by tool result

Open
#217 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Python
Stars
3.1k
Forks
261
Avg merge
3h 28m
Merged PRs (30d)
13

Description

Summary

When a session crashes mid-tool-execution, resuming it fails with an Anthropic HTTP 400 error due to consecutive user-role messages in the API request. This creates an unresumable session that requires manual transcript surgery to fix.

Affected component: amplifier-core (session resume logic)

Reproduction

  1. Start a session with tool use
  2. Session crashes mid-tool-execution (network timeout, process kill, etc.) — leaving an assistant message with tool_calls but no corresponding tool_result in the transcript
  3. Attempt to resume the session with amplifier session resume <id>
  4. HTTP 400 from Anthropic

Root Cause

The resume logic strips orphaned assistant tool_use messages (correctly — can't send tool_use without tool_result). However, this leaves the preceding tool_result as the effective last message, which maps to role: "user" in the Anthropic API. The resume prompt is then appended as another role: "user" message, creating consecutive same-role messages that Anthropic rejects.

The sequence that fails:

[N-1] user (tool_result)     ← was paired with the now-stripped tool_use
[N]   user (resume prompt)   ← injected by resume logic
→ HTTP 400: consecutive user messages

A similar collision occurs when hooks (e.g., hooks-status-context) inject user-role content between a tool_result and the next API call.

Observed Impact

  • Session ba107234-91eb-403f-a671-a668a3f614de required four manual transcript repairs due to this bug
  • Each resume attempt hit HTTP 400, crashed again, and left additional corrupt state
  • The only workaround is manual transcript truncation back to a safe assistant text message with no pending tool calls

Suggested Fix

When constructing the API request for a resumed session:

  1. After stripping orphaned tool calls, check if the effective last message is role: "user"
  2. If so, either:
    • Merge the resume prompt into the existing user message, OR
    • Insert a synthetic assistant acknowledgment (e.g., "Resuming session.") before the resume prompt to maintain role alternation
  3. Apply the same merge logic when hooks inject user-role content after a tool_result

More generally, the message construction pipeline should enforce role alternation as a post-processing step before sending to any provider that requires it.

Environment

  • Platform: WSL2 (Linux 6.6.87.2-microsoft-standard-WSL2)
  • Provider: Anthropic (claude-opus-4-6)
  • Session: ba107234-91eb-403f-a671-a668a3f614de

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in amplifier-core's session resume logic and trace the request built by amplifier session resume <id>, especially orphaned tool-call handling. Reproduce the Anthropic HTTP 400 with the documented session sequence, then inspect how hooks-status-context adds user content. Done means resumed requests avoid consecutive user roles and regression coverage includes orphaned tool calls and hook-injected content.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
backend-api-design
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
42/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.