Summary
opencode run intermittently hangs before creating a session. When it happens the process stays alive but produces zero stdout, emits no error, and never progresses past message=init in the log. The only way out is an external timeout.
The failure is intermittent, not deterministic. Over 61 invocations in one day I measured a 44% success rate (27/61), with hourly rates swinging between 8% and 77%. A later controlled 40-run trial in a "good" window produced 40/40 successes, so the failure window and the healthy window can be minutes apart with no configuration change in between.
Read-only subcommands (--version, agent list, models) always respond instantly, even while run is hanging.
Environment
|
|
| opencode |
1.18.4 (also reproduced on 1.17.11) |
| Install |
npm install -g opencode-ai (nvm-managed prefix, no sudo) |
| OS |
macOS 26.5.2 (build 25F84), Darwin 25.5.0, arm64 |
| Hardware |
Apple M4 Pro, 48 GB unified memory |
| Node |
v24.17.0 (nvm) |
| npm |
12.0.0 |
| Provider |
Ollama 0.32.3 via @ai-sdk/openai-compatible at http://127.0.0.1:11434/v1 |
Relevant config (~/.config/opencode/opencode.jsonc), though the issue reproduces with no user config at all:
Steps to reproduce
Reproduction is probabilistic. There is no known trigger; the same command succeeds or hangs depending on when it is run.
mkdir -p /tmp/oc-repro && cd /tmp/oc-repro
timeout 120 opencode run "answer in one word: what is 1+1?"
echo "exit=$?" # 0 when it works (~19s), 124 when it hangs
Run this repeatedly with a gap between attempts. In failure windows it hangs on most attempts; in healthy windows it succeeds every time in ~19 seconds.
Do not judge by exit code alone. Because stdout is buffered until completion, a hung run and a slow run look identical from the shell. The reliable discriminator is whether a session was created:
grep -c 'message=created' ~/.local/share/opencode/log/opencode.log
Observed behaviour
Log signature
A successful run progresses through:
init → created → event → loop → shell → init → booting → stream → loop → exiting loop → disposing instance
A hung run stops dead at the first init:
timestamp=... message="creating instance" directory=/tmp/oc-repro
timestamp=... message=fromDirectory directory=/tmp/oc-repro
timestamp=... message=bootstrapping directory=/tmp/oc-repro
timestamp=... message=loading path=/Users/<user>/.config/opencode/config.json
timestamp=... message=loading path=/Users/<user>/.config/opencode/opencode.json
timestamp=... message=loading path=/Users/<user>/.config/opencode/opencode.jsonc
timestamp=... message="all LSPs are disabled"
timestamp=... message="all formatters are disabled"
timestamp=... message=init
<nothing further — process stays alive until killed>
No created, no stream, no error, no warning at --log-level DEBUG.
Timing is bimodal, not a slowdown
Across 40 controlled runs, every successful run completed in 18–19 seconds (min 18, max 19). Hung runs never complete — observed up to 900s. There is no middle ground: a run either finishes in ~19s or does not progress at all.
Network evidence — connection to models.dev held open with no progress
During a hung run, lsof showed an ESTABLISHED connection to 172.67.69.147:443 held for the entire 30-second sampling window while the run made no progress:
$ lsof -nP -a -p <pid> -i
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
opencode. 14462 vinyl 15u IPv4 ... 0t0 TCP 192.168.x.x:50476->172.67.69.147:443 (ESTABLISHED)
172.67.69.147 resolves as one of the A records for models.dev:
$ dig +short models.dev
104.26.9.108
104.26.8.108
172.67.69.147
(registry.npmjs.org resolves to a different range, 104.16.x.x, so this is models.dev specifically.)
Meanwhile the host itself was perfectly reachable from the same machine at the same time:
$ curl -s -o /dev/null -w "namelookup=%{time_namelookup} connect=%{time_connect} tls=%{time_appconnect} total=%{time_total}\n" https://models.dev/
namelookup=0.001497 connect=0.140799 tls=0.287761 total=1.107086 # HTTP 200
System resolver was also instant (socket.getaddrinfo("models.dev", 443) → 0.00s).
So the remote endpoint was healthy while opencode sat on an established connection to it without progressing.
A second, different hang shape
Not every hang looks the same. In other hung runs, lsof showed the process holding no sockets at all — not to models.dev, and not even to the local Ollama endpoint on 127.0.0.1:11434:
t=2 PID=14286 connections=[none]
t=4 PID=14286 connections=[none]
...
t=30 PID=14286 connections=[none]
This suggests there may be more than one stall path, or a stall that occurs before any socket is opened. I could not determine which.
OPENCODE_OFFLINE=1 does not suppress the models.dev request
In a controlled, interleaved 40-run trial (20 with OPENCODE_OFFLINE=1, 20 without, alternating, fixed 45s gap between runs), connections to models.dev were sampled during every run:
| Arm |
Runs |
Sessions created |
models.dev connection observed |
OPENCODE_OFFLINE=1 |
20 |
20/20 |
4 |
| control |
20 |
20/20 |
4 |
Identical. The environment variable did not reduce contact with models.dev.
Note this sampling is a lower bound: connections were polled every 2s, so short-lived requests during fast (~19s) runs are frequently missed. A zero should be read as "not observed", not "did not happen". The signal that matters here is that both arms show the same rate.
Frequency data
Uncontrolled observations, 2026-07-24 — 61 opencode run invocations, classified by whether a session was created:
| Hour (UTC) |
Sessions created / attempts |
| 01–09 |
10/13 (77%) |
| 10 |
4/9 (44%) |
| 11–12 |
1/13 (8%) |
| 13 |
0/4 (0%) |
| 14–15 |
12/22 (55%) |
| Total |
27/61 (44%) |
Controlled trial, 15:26–16:08 UTC — 40 runs, alternating arms, fixed 45s gap: 40/40 succeeded, all in 18–19s. This window began roughly 10 minutes after a stretch of 6 consecutive failures, with no configuration change in between.
What was ruled out
Every one of these was tested; the hang reproduced after each:
| Hypothesis |
How it was ruled out |
| User config |
Rolled back through three prior states, then removed opencode.jsonc entirely |
| Project-level config |
Reproduced both with and without a project opencode.jsonc |
| Corrupted install |
Clean reinstall to 1.18.4 with postinstall scripts explicitly allowed |
| Plugins |
Reproduced with --pure |
| Local state / DB |
Deleted opencode.db, -shm, -wal; recreated (56 tables) and still hangs |
| OS-level resource leak |
Full machine restart |
| Binary integrity / Gatekeeper |
Mach-O arm64, no com.apple.quarantine (only com.apple.provenance) |
| Ollama unhealthy |
Direct /api/generate call answered in 1.7s while run was hanging |
| DNS / network path |
getaddrinfo 0.00s; curl https://models.dev/ → HTTP 200 in 1.1s |
| Disk / memory |
69 GiB free, ~50% memory free |
| Auto-update in flight |
--version instant; no update activity in logs |
One incidental finding while reinstalling: with npm's allowScripts policy active, npm install -g opencode-ai@latest completes but silently skips the postinstall script, leaving a broken install whose --version prints "reinstall opencode-ai without the --ignore-scripts flag". Given autoupdate: true is the default, a self-update under that policy could leave users in a broken state. This is separate from the hang (the hang persisted after a correct reinstall) but may be worth handling.
What I think is happening
Stated as a hypothesis, not a conclusion — I do not have enough evidence to confirm it:
opencode appears to contact models.dev during startup, and at least one code path can wait on that request indefinitely with no timeout and no error surfaced. The observed ESTABLISHED-but-idle connection is consistent with this. What I cannot explain is the second hang shape where no sockets exist at all.
If startup does depend on a network fetch, a bounded timeout with a fallback to cached data (and a log line on failure) would turn a silent indefinite hang into a recoverable, diagnosable condition.
What would help
- Is a
models.dev (or other remote) fetch on the run startup path, and does it have a timeout?
- Is there a supported way to make startup fully offline?
OPENCODE_OFFLINE=1 did not appear to affect the request in my testing.
- Would you accept a log line at the point where init blocks, so this failure is diagnosable without
lsof?
I have raw per-run data (timestamps, exit codes, elapsed, session-created flags, connection samples) for all 101 runs and can attach it if useful.
Summary
opencode runintermittently hangs before creating a session. When it happens the process stays alive but produces zero stdout, emits no error, and never progresses pastmessage=initin the log. The only way out is an external timeout.The failure is intermittent, not deterministic. Over 61 invocations in one day I measured a 44% success rate (27/61), with hourly rates swinging between 8% and 77%. A later controlled 40-run trial in a "good" window produced 40/40 successes, so the failure window and the healthy window can be minutes apart with no configuration change in between.
Read-only subcommands (
--version,agent list,models) always respond instantly, even whilerunis hanging.Environment
npm install -g opencode-ai(nvm-managed prefix, no sudo)@ai-sdk/openai-compatibleathttp://127.0.0.1:11434/v1Relevant config (
~/.config/opencode/opencode.jsonc), though the issue reproduces with no user config at all:{ "$schema": "https://opencode.ai/config.json", "share": "disabled", "autoupdate": true, "model": "ollama/qwen3-coder:30b", "provider": { "ollama": { "npm": "@ai-sdk/openai-compatible", "name": "Ollama (Local)", "options": { "baseURL": "http://127.0.0.1:11434/v1", "timeout": 1800000 } } } }Steps to reproduce
Reproduction is probabilistic. There is no known trigger; the same command succeeds or hangs depending on when it is run.
Run this repeatedly with a gap between attempts. In failure windows it hangs on most attempts; in healthy windows it succeeds every time in ~19 seconds.
Do not judge by exit code alone. Because stdout is buffered until completion, a hung run and a slow run look identical from the shell. The reliable discriminator is whether a session was created:
Observed behaviour
Log signature
A successful run progresses through:
A hung run stops dead at the first
init:No
created, nostream, no error, no warning at--log-level DEBUG.Timing is bimodal, not a slowdown
Across 40 controlled runs, every successful run completed in 18–19 seconds (min 18, max 19). Hung runs never complete — observed up to 900s. There is no middle ground: a run either finishes in ~19s or does not progress at all.
Network evidence — connection to
models.devheld open with no progressDuring a hung run,
lsofshowed an ESTABLISHED connection to172.67.69.147:443held for the entire 30-second sampling window while the run made no progress:172.67.69.147resolves as one of the A records formodels.dev:(
registry.npmjs.orgresolves to a different range,104.16.x.x, so this ismodels.devspecifically.)Meanwhile the host itself was perfectly reachable from the same machine at the same time:
System resolver was also instant (
socket.getaddrinfo("models.dev", 443)→ 0.00s).So the remote endpoint was healthy while opencode sat on an established connection to it without progressing.
A second, different hang shape
Not every hang looks the same. In other hung runs,
lsofshowed the process holding no sockets at all — not tomodels.dev, and not even to the local Ollama endpoint on127.0.0.1:11434:This suggests there may be more than one stall path, or a stall that occurs before any socket is opened. I could not determine which.
OPENCODE_OFFLINE=1does not suppress themodels.devrequestIn a controlled, interleaved 40-run trial (20 with
OPENCODE_OFFLINE=1, 20 without, alternating, fixed 45s gap between runs), connections tomodels.devwere sampled during every run:models.devconnection observedOPENCODE_OFFLINE=1Identical. The environment variable did not reduce contact with
models.dev.Note this sampling is a lower bound: connections were polled every 2s, so short-lived requests during fast (~19s) runs are frequently missed. A zero should be read as "not observed", not "did not happen". The signal that matters here is that both arms show the same rate.
Frequency data
Uncontrolled observations, 2026-07-24 — 61
opencode runinvocations, classified by whether a session was created:Controlled trial, 15:26–16:08 UTC — 40 runs, alternating arms, fixed 45s gap: 40/40 succeeded, all in 18–19s. This window began roughly 10 minutes after a stretch of 6 consecutive failures, with no configuration change in between.
What was ruled out
Every one of these was tested; the hang reproduced after each:
opencode.jsoncentirelyopencode.jsonc--pureopencode.db,-shm,-wal; recreated (56 tables) and still hangscom.apple.quarantine(onlycom.apple.provenance)/api/generatecall answered in 1.7s whilerunwas hanginggetaddrinfo0.00s;curl https://models.dev/→ HTTP 200 in 1.1s--versioninstant; no update activity in logsOne incidental finding while reinstalling: with npm's
allowScriptspolicy active,npm install -g opencode-ai@latestcompletes but silently skips the postinstall script, leaving a broken install whose--versionprints "reinstall opencode-ai without the --ignore-scripts flag". Givenautoupdate: trueis the default, a self-update under that policy could leave users in a broken state. This is separate from the hang (the hang persisted after a correct reinstall) but may be worth handling.What I think is happening
Stated as a hypothesis, not a conclusion — I do not have enough evidence to confirm it:
opencode appears to contact
models.devduring startup, and at least one code path can wait on that request indefinitely with no timeout and no error surfaced. The observed ESTABLISHED-but-idle connection is consistent with this. What I cannot explain is the second hang shape where no sockets exist at all.If startup does depend on a network fetch, a bounded timeout with a fallback to cached data (and a log line on failure) would turn a silent indefinite hang into a recoverable, diagnosable condition.
What would help
models.dev(or other remote) fetch on therunstartup path, and does it have a timeout?OPENCODE_OFFLINE=1did not appear to affect the request in my testing.lsof?I have raw per-run data (timestamps, exit codes, elapsed, session-created flags, connection samples) for all 101 runs and can attach it if useful.