You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
OpenCode keeps attempting connection to unreachable provider without giving a connection error #40319
Using OpenCode 1.18.11 on Linux I pointed a custom OpenAI Compatible provider at a non-working local address. opencode run kept retrying for more than 60 seconds without showing an error or exiting. Debug logs showed that the connection had failed. I was expecting a few retries, a visible connection error, and a failure when it exits.
The output remains empty and the process keeps retrying. A 60-second timeout ends the process with exit code 124 while the debug logs show "AI_APICallError: Cannot connect to API"
We hit the exact same behavior (filed #40330 before spotting this one — closing ours as duplicate). Since we had traced it through the v1.18.11 source before filing, here is the root-cause analysis in case it helps:
@ai-sdk/provider-utils's handleFetchError marks every network-level failure — including ECONNREFUSED — as APICallError { isRetryable: true }.
opencode propagates the flag untouched: packages/opencode/src/session/message-v2.ts:676-704 and packages/opencode/src/provider/error.ts:181. There is no branch for ECONNREFUSED/ENOTFOUND/EHOSTUNREACH (contrast with the explicit ECONNRESET handling at message-v2.ts:625-637).
The retry policy never gives up: packages/opencode/src/session/retry.ts:68-79 always returns an object while isRetryable is true, and retry.ts:176-200 builds a Schedule with no Schedule.recurs and no time budget — only the delay is capped (RETRY_MAX_DELAY_NO_HEADERS = 30_000, retry.ts:26-28). Net effect: one attempt every 30 s, forever.
packages/opencode/src/session/processor.ts:660-675 applies Effect.retry(...)beforeEffect.catch(halt), so halt is unreachable — no session.error, never idle.
Non-interactive mode compounds it: packages/opencode/src/cli/cmd/run.ts:789-793 only exits on idle, and the retry status events (emitted at processor.ts:664-672) are consumed by the TUI but nowhere in run.ts — not even with --format json. So opencode run shows literally nothing while it loops.
No configuration escape: timeout/headerTimeout/chunkTimeout (provider.ts:1737-1768) only arm on an established connection, and headerTimeout gets a default only for the openai provider (provider.ts:208).
Reproduced on 1.17.4, 1.17.13, 1.17.14 and 1.18.11 with a minimal isolated config (fresh XDG_CONFIG_HOME/XDG_DATA_HOME, one custom provider, no plugins). A live-but-slow endpoint is fine; the trigger is strictly connection refused. A 30-second no-GPU repro script is in #40330.
Suggested fixes (any subset helps): treat ECONNREFUSED/ENOTFOUND/EHOSTUNREACH as non-retryable (or bounded), add a max-attempts/time budget to the schedule, surface the retry status in run mode, and/or expose --max-retries/--timeout on opencode run. Note #39790 traces to the same unbounded SessionRetry.policy() via 429s.
Thanks for tracing this so clearly and consolidating #40330 here. This explains exactly what we were seeing, especially why opencode run stays silent without returning to idle. The cross-version reproduction and no-GPU script should make this much easier to act on. Much appreciated.
Activity
github-actions commentedon Aug 3, 2026
This issue might be a duplicate of existing issues. Please check:
Martossien commentedon Aug 3, 2026
We hit the exact same behavior (filed #40330 before spotting this one — closing ours as duplicate). Since we had traced it through the v1.18.11 source before filing, here is the root-cause analysis in case it helps:
@ai-sdk/provider-utils'shandleFetchErrormarks every network-level failure — includingECONNREFUSED— asAPICallError { isRetryable: true }.packages/opencode/src/session/message-v2.ts:676-704andpackages/opencode/src/provider/error.ts:181. There is no branch forECONNREFUSED/ENOTFOUND/EHOSTUNREACH(contrast with the explicitECONNRESEThandling atmessage-v2.ts:625-637).packages/opencode/src/session/retry.ts:68-79always returns an object whileisRetryableis true, andretry.ts:176-200builds aSchedulewith noSchedule.recursand no time budget — only the delay is capped (RETRY_MAX_DELAY_NO_HEADERS = 30_000,retry.ts:26-28). Net effect: one attempt every 30 s, forever.packages/opencode/src/session/processor.ts:660-675appliesEffect.retry(...)beforeEffect.catch(halt), sohaltis unreachable — nosession.error, neveridle.packages/opencode/src/cli/cmd/run.ts:789-793only exits onidle, and theretrystatus events (emitted atprocessor.ts:664-672) are consumed by the TUI but nowhere inrun.ts— not even with--format json. Soopencode runshows literally nothing while it loops.timeout/headerTimeout/chunkTimeout(provider.ts:1737-1768) only arm on an established connection, andheaderTimeoutgets a default only for theopenaiprovider (provider.ts:208).Reproduced on 1.17.4, 1.17.13, 1.17.14 and 1.18.11 with a minimal isolated config (fresh
XDG_CONFIG_HOME/XDG_DATA_HOME, one custom provider, no plugins). A live-but-slow endpoint is fine; the trigger is strictly connection refused. A 30-second no-GPU repro script is in #40330.Suggested fixes (any subset helps): treat
ECONNREFUSED/ENOTFOUND/EHOSTUNREACHas non-retryable (or bounded), add a max-attempts/time budget to the schedule, surface theretrystatus inrunmode, and/or expose--max-retries/--timeoutonopencode run. Note #39790 traces to the same unboundedSessionRetry.policy()via 429s.grantwilliams-ai commentedon Aug 3, 2026
Thanks for tracing this so clearly and consolidating #40330 here. This explains exactly what we were seeing, especially why opencode run stays silent without returning to idle. The cross-version reproduction and no-GPU script should make this much easier to act on. Much appreciated.
github-actions commentedon Oct 4, 2026
To stay organized issues are automatically closed after 60 days of no activity. If the issue is still relevant please open a new one.