Skip to content

opencode run intermittently hangs during init — no session created, no output, no error (~56% failure rate observed) #38723

Description

@VinylStage

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:

{
  "$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.

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.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions