#4129·9router

CommandCode provider: retry transient network drops and prevent fake stop chunks

Author: Christian-GennariCreated Sep 17, 2026Updated Sep 17, 2026

Hey!

Ran into an issue with CommandCode streams dropping unexpectedly and getting treated as successful turns:

  1. Transient upstream drops treated as finished content: CommandCode occasionally drops connections during initial token generation or reasoning phases with {"type": "error", "error": {"type": "server_error", "message": "Network connection lost."}}. In commandcode-to-openai.js, this was formatted as [CommandCode error: ...] text and emitted with finish_reason: "stop". Consuming clients (like Hermes, OpenCode, Codex) treat this as a successful 200 completion rather than a retryable drop.
  2. Missing upstream retry on initial inspection: inspectAndWrapCommandCodeResponse catches errors prior to token emission, but CommandCodeExecutor.execute() immediately surfaced the error without retrying upstream. Since CommandCode connection drops are often transient server disconnects, an immediate retry succeeds in almost all cases.
  3. Missing reasoning block on tool calls in multi-turn: When returning assistant turns containing tool calls to CommandCode, omitting a {type: "reasoning"} block can trigger API rejection with The reasoning_content in the thinking mode must be passed back to the API.

To be clear, the primary root cause for the connection drops is upstream instability on CommandCode's own infrastructure (tracked in CommandCodeAI/command-code#597). This fix provides defensive resiliency on 9Router's side so clients are shielded from those drops while CommandCode resolves their backend stability.

I put together a fix with tests that:

  • Adds automatic retry logic (up to 2 attempts with backoff) in CommandCodeExecutor.execute() when upstream returns retryable 502/503/504 errors before tokens flow.
  • Throws on mid-stream error events in commandcode-to-openai.js rather than emitting a fake successful finish_reason: "stop" chunk.
  • Ensures assistant messages with tool calls or thinking content include a reasoning block in openai-to-commandcode.js.
  • Adds unit tests covering retry recovery in tests/unit/commandcode-executor.test.js.

Opening a PR with the changes shortly.