Skip to content

Claude proxy: an Esc mid-stream never ends the flow, so the phase stays busy (stuck Thinking, goal-loop Resume) #1040

Closed

Description

@Juliusolsson05

Found by the #1028 re-review. The review read the mitmproxy 12.2.2 source and reproduced the shape with probes.

What happens

When the user presses Esc while Claude is streaming, Claude Code closes the HTTP connection.

  • mitmproxy: it reports a client disconnect only through its error hook. _http1.py wait() raises RequestProtocolError("Client disconnected."), which goes to handle_protocol_error. The end-of-stream call the addon turns into response-end runs only on a normal end of message (http/__init__.py:460-462).
  • Our addon: mitmAddon.py (claude-code-headless) has no error hook, so nothing is emitted.
  • The adapter: ClaudeProxyAdapter.handleTransportEvent never reaches onEnd. The stream phase stays at the last working phase (thinking, responding, tool-input, or requesting if the Esc came before the first chunk).
  • What resets it: only the next flow's first chunk (if the old flow is more than 30 s stale) or sealFlowsSilentSince after a machine sleep.

Effects

Fix

  • In mitmAddon.py, add an error(flow) hook that emits a terminal transport event for the flow.
  • In ClaudeProxyAdapter, seal that flow and publish idle for it when it owns the phase.
  • Test: a recorded or captured disconnect sequence, through the real adapter.

Related: the planned adapter change that classifies cc_is_subagent flows before first-chunk promotion. It also removes the subagent demotion idle edge (#1024, and the re-review's probe H).

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

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions