anomalyco / anomalyco/opencode

chunkTimeout and timeout are silently ignored on the v2 packages/llm provider path

Open
#46,692 3 comments 0 reactions 1 assignee View on GitHub

@nexxeln is already working on this.

Since Sep 2, 2026.

2.0
Dominant language
TypeScript
Stars
209k
Forks
27.5k
PR merge metrics
PR metrics pending

Description

Description

chunkTimeout and timeout are accepted by the provider config schema and documented, but packages/llm never reads them. Providers routed through the v2 native path therefore have no client-side stall bound at all, and the settings fail silently.

Implemented in two places, neither on the v2 path:

  • packages/core/src/aisdk.ts:78 (AI SDK path)
  • packages/opencode/src/provider/provider.ts:1789 (v1 path)

Declared and documented:

  • packages/core/src/v1/config/provider.ts — schema: "If no chunk arrives within this window, the request is aborted."
  • packages/web/src/content/docs/config.mdx — same promise
  • packages/opencode/test/provider/header-timeout.test.ts — passing test: "chunkTimeout raises a response stream error when SSE body stalls"

Not implemented:

  • packages/llm/src/providers/azure.ts routes via OpenAIResponses.route.with({ id: "azure-openai-responses" })
  • packages/llm/src contains no timeout application. The only Timeout reference is classification, packages/llm/src/route/executor.ts:319 (Cause.isTimeoutError).

Note the schema lives under core/src/v1/config/provider.ts — this looks like a v1-era option that was not carried into packages/llm.

Impact. A half-open or stalled SSE stream is bounded only by Bun's TCP keepalive (src/http/lib.rs set_keep_alive(true, 60) plus hardcoded TCP_KEEPINTVL=1 / TCP_KEEPCNT=10 in packages/bun-usockets/src/bsd.c), so ~70s. If the peer stays alive but stops sending, nothing bounds it at all.

Against a real Azure OpenAI endpoint whose upstream APIM gateway RSTs mid-stream on ~2% of requests, every occurrence costs ~70s of dead time before the retry fires, and the turn surfaces only as Decode error (200 POST ...) — see #42482, whose cited path packages/ai/src/route/executor.ts is now packages/llm/src/route/executor.ts.

Secondary observation. The documented config key appears to be options, but only settings took effect on this build: providers.azure.settings.baseURL redirected the provider, providers.azure.options.baseURL did not. Worth confirming whether the v2 schema and docs disagree.

Steps to reproduce
  1. Run a local server that returns 200 with Content-Type: text/event-stream, sends two valid SSE frames, then holds the socket open and sends nothing further.

  2. Point a packages/llm-routed provider at it and set a short chunk timeout:

{
  "providers": {
    "azure": {
      "settings": {
        "baseURL": "http://127.0.0.1:8899/openai/v1",
        "chunkTimeout": 15000
      }
    }
  }
}
  1. opencode run --standalone --model azure/<model> "hi"

Expected: request aborts at ~15s with a stream error.

Actual: no abort. I killed it externally at 100s. Same result with "timeout": 20000 (killed at 80s). baseURL in the same settings block did take effect, so the block is parsed and applied.

OpenCode version

0.0.0-beta-18743

Operating System

macOS 26.5.2 (Darwin arm64)

Terminal

Ghostty

Contributor guide

Open the contributing guide

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.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.