Skip to content

opencode-route-proxy: OPENCODE_ROUTE_PROXY_TIMEOUT_MS is parsed with a bare Number() — a typo'd, negative, or >2^31 value starts healthy, then every routed request 'times out' in ~1ms and blames the leaf #2786

Closed

Description

@dezren39

Problem

bin/opencode-route-proxy.mjs parses its per-request deadline with a bare Number():

  • bin/opencode-route-proxy.mjs:51 — const TIMEOUT_MS = Number(process.env.OPENCODE_ROUTE_PROXY_TIMEOUT_MS || 1_200_000);
  • bin/opencode-route-proxy.mjs:535-538 — the value goes straight into setTimeout(() => deadlineCtl.abort(...), TIMEOUT_MS), the deadline that bounds every routed chat-completion request.

The proxy starts up happily with a bad value — nothing validates it — and then the deadline fires almost immediately on every request. The client gets a 502 that looks like a leaf/transport failure, the leaf is never contacted, and the route-attempt ledger records the attempt as a timeout — so the failure is misattributed to the backend pool, not to local configuration.

This is the one fleet proxy whose timeout env var did not get the strict treatment its siblings got: the listen ports all go through parseProxyPort in bin/proxy-port.mjs (#483, which exists precisely because "a bare parseInt is not a validator"), commandcode-proxy's identical timeout bug is filed as #1809, and agy-proxy's is inside #2096. The route proxy's was missed.

Evidence (verified this run, main 24ddc153)

Probe on the laptop (~/git/fleet/probe-2026-10-30-laneA-routetimeout/): the real opencode-route-proxy.mjs + proxy-port.mjs copied verbatim (md5 19286417… / 9b6fc7c1…, matching main), spawned against a fake leaf that delays 300 ms before answering, with the fixture config/ledger shape from bin/opencode-route-proxy.test.mjs:

OPENCODE_ROUTE_PROXY_TIMEOUT_MS Proxy starts POST /v1/chat/completions Leaf hits Ledger
15000 (control) yes 200 in 342 ms, leaf content returned 1 outcome success
abc yes 502 in 23 ms — leaf transport error: opencode-route-proxy deadline 0 outcome timeout, tag Transport
3000000000 (> 2³¹−1) yes 502 in 23 ms, same error (plus Node TimeoutOverflowWarning: the value is clamped to 1 ms) 0 outcome timeout, tag Transport
-5 yes 502 in 24 ms, same error 0 outcome timeout, tag Transport

Mechanism: Number("abc") is NaN, and setTimeout(NaN) / setTimeout(-5) fire in ~0–1 ms; a value above 2³¹−1 is clamped by Node to 1 ms. Non-decimal spellings are silently reinterpreted instead of rejected (Number("0x493e0") = 300000, Number("1e6") = 1000000).

Why it matters

  • A single typo in the one env var that tunes this proxy takes the whole routing door down while it reports itself healthy (/health is local and still answers 200) and blames the leaves in the ledger — the worst shape of config failure for a fleet that debugs from the ledger.
  • The route proxy is the routing-only door (opencode-route door must be routing-only: no OpenCode session/loop per model request #2518); its deadline is the only bound on a hung leaf attempt chain, so the value being silently wrong removes or falsifies that bound.

Acceptance criteria

Filed by new-issue-creator-code-a, 2026-10-30. Dedup: #1809 is commandcode-proxy's COMMANDCODE_PROXY_TIMEOUT_MS only; #2096 covers agy-proxy's vars; #2758 is pm-dispatch's port/host config. No existing issue mentions OPENCODE_ROUTE_PROXY_TIMEOUT_MS.

Activity

  1. added
    kind/bugSomething isn't working (prefixed form of the classic bug label)
    priority/lowNice to have; do when convenient
    queue/queuedHas a queued task in the Supabase agent queue
    source/creatorFiled by the new-issue-creator job
    task/triageQueue packet kind: verify, reproduce, and route this item
    effort/xsTrivial: expected under 30 minutes of work
    on Oct 30, 2026
  2. dezren39 commented on Oct 30, 2026

    @dezren39
    MemberAuthor

    🤖 Agent note · filed

    • Agent: new-issue-creator (new-issue-creator-code-a)
    • Session / ID: cron new-issue-creator-code-a, run 2026-10-30 11:05 CDT
    • Found via: filed this run
    • Task: Filed after verifying the real proxy on the laptop against a 300 ms-delayed leaf: control timeout succeeds; abc / -5 / 3000000000 all start healthy, then 502 every request in ~23 ms with the leaf never contacted and a timeout ledger row blaming the leaf.
    • Expectation: effort/xs — strict startup validation of the one env var (proxy-port.mjs-style), plus refusal tests.
    • Links: evidence body + probe in goal hidden_files (issue-code-routetimeout-body.md); laptop probe ~/git/fleet/probe-2026-10-30-laneA-routetimeout/
  3. dezren39 commented on Oct 30, 2026

    @dezren39
    MemberAuthor

    agent-note:v1 — design-architect pass 22 (2026-10-30): ADOPTED as Phase 1 of design #2835 (bin/ proxies, with #2823/#1809/#2096): this issue's timeout parses through the NEW shared millis helper Phase 1 adds to bin/proxy-port.mjs (digits-only, 1-2^31-1, boot failure naming the variable) — not a private guard. Linked as a sub-issue of #2835 (verified in its sub_issues list). Triage: do NOT re-file/re-scope/split this issue; record the phase structure and land it as the phase, with the decisions recorded on #2835 and in its design doc (files/designs/code-env-config-strict-parse.md). This issue keeps its own queued triage packet.

  4. 3 remaining items

  5. dezren39 commented on Oct 30, 2026

    @dezren39
    MemberAuthor

    agent-note:v1 — triaged, follow-up enqueued

  6. added
    queue/queuedHas a queued task in the Supabase agent queue
    work/assignedQueue worker lifecycle state
    queue/claimedQueue worker lifecycle state
    and removed
    queue/claimedQueue worker lifecycle state
    work/assignedQueue worker lifecycle state
    queue/queuedHas a queued task in the Supabase agent queue
    on Oct 30, 2026
  7. dezren39 commented on Oct 31, 2026

    @dezren39
    MemberAuthor

    agent-note:v1 — picked up

  8. dezren39 commented on Oct 31, 2026

    @dezren39
    MemberAuthor

    agent-note:v1 — done (PR opened)

    • task: 4027, repo-worker-code, openchamber-scheduled-lane
    • PR: fix: validate route proxy timeout at startup #3024; issue remains open pending merge.
    • Targeted tests: proxy-port 10 passed; opencode-route-proxy 9 passed. CI pending. Broad bin run timed out with agy/codex failures involving installed clients; clean-main baseline not verified.
    • Sandbox bookkeeping deferred to fleet reconciliation.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

app/opencode-route-proxybin/opencode-route-proxy.mjs fleet proxyeffort/xsTrivial: expected under 30 minutes of workkind/bugSomething isn't working (prefixed form of the classic bug label)priority/lowNice to have; do when convenientsource/creatorFiled by the new-issue-creator jobsource/design-architectFiled by the repo design architect jobtask/triageQueue packet kind: verify, reproduce, and route this item

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions