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
Concurrent opencode run workers can fail at startup with database is locked #33320
Running several top-level opencode run workers concurrently can still fail at startup with an unhandled SQLite lock error on OpenCode 1.17.8.
Observed worker log:
Error: Unexpected error
database is locked
This looks related to #21215 and #19521, but this reproduction is on 1.17.8 and happens immediately during a headless worker startup batch. The affected worker exits before it reads the prompt or produces any useful output.
Expected behavior: concurrent headless workers should either start reliably, retry the local database write with a bounded busy timeout/backoff, or fail with an actionable error that names the contended resource and recommended isolation setting.
Plugins
--pure was used in synthetic probes. The wrapper run used a generated project-local config for an OpenAI-compatible OpenRouter provider.
OpenCode version
1.17.8
Steps to reproduce
Configure an OpenAI-compatible provider/model. In my reproduction, the model was openrouter/cohere/north-mini-code:free.
Launch multiple headless workers close together from the same OS user account:
Repeating the run with a distinct generated OPENCODE_CONFIG_DIR per worker did not eliminate the startup lock failure, which suggests the contention is in shared OpenCode state rather than the generated provider config file.
Screenshot and/or share link
No screenshot/share link. The relevant stderr excerpt is included above.
Operating System
macOS 26.5.1
Terminal
Headless opencode run launched from tmux windows in zsh.
Also reproducible in the interactive TUI (not just headless run), on opencode 1.17.15–1.17.18, macOS (Apple Silicon) + Linux: when the shared opencode.db is locked at boot, the TUI renders a blank screen with no visible error — the failure only appears in ~/.local/share/opencode/log/*.log:
database is locked → LockTimeoutError → Unexpected server error
around InstanceStore.boot / Project.fromDirectory (the startup upsert into project).
The affected instance never renders, and in the interactive case there's no actionable message and (in some paths) no non-zero exit — users can't tell "failed" from "hung," so diagnosis is slow.
Ask: surface a fatal, user-visible DB error (and exit non-zero) that names the contended DB path and suggests closing other instances, instead of a blank TUI. Happy to help repro.
Additional Windows reproduction on OpenCode 1.18.25 confirming this is still present, plus a recovery path that preserved all existing session/chat history.
Environment
Windows / PowerShell
OpenCode 1.18.25
Multiple concurrent OpenCode runs sharing the same OpenCode data directory
Several concurrent runs began hitting LockTimeoutError / SQLiteError: database is locked during session/message writes. After that, every new OpenCode invocation failed during startup in Project.fromDirectory() while attempting the shared project upsert.
The CLI only surfaced:
Error: Unexpected server error. Check server logs for details.
The failure reproduced from the project directory, the user home directory, and a fresh temp directory, confirming that it was shared/global OpenCode state rather than project configuration.
Important recovery finding: a lingering OpenCode process was still holding the database. Terminating that process immediately restored normal OpenCode startup. We did not delete opencode.db, the WAL, or any OpenCode state, so all existing session/chat history was preserved.
This seems worth making part of the recovery path because users encountering a persistent DB lock may otherwise follow advice to delete/reset the database and unnecessarily lose their history.
Also, OpenCode 1.18.25 already sets:
PRAGMA busy_timeout =5000
so the busy timeout alone does not prevent this failure mode.
A useful recovery flow could be:
Retry transient lock failures with bounded backoff.
If still locked, expose the actual SQLite lock error and DB path rather than only Unexpected server error.
Detect likely OpenCode processes that may still hold the shared DB and show their PID/command line.
In interactive mode, offer an explicit user-confirmed option to terminate selected OpenCode processes.
Verify the selected process actually exited.
Verify the database is no longer locked/writable.
Retry Project.fromDirectory() and only report recovery once startup succeeds.
I would not auto-kill another OpenCode process by default, since it may still be doing useful work. But an explicit terminate → verify exit → verify DB unlock → retry flow would make this recoverable while protecting users from unnecessarily deleting their chat history.
Thanks for the report! OpenCode 2.0 is now out and development is focused on V2, so we're closing issues filed against OpenCode 1. Please upgrade (opencode upgrade --major, details: https://anoma.ly/notes/opencode-2-0), and if this is still relevant on 2.0, reopen this issue or open a new one with your 2.0 version.
Activity
github-actions commentedon Jun 22, 2026
This issue might be a duplicate of existing issues. Please check:
SQLITE_BUSY/busy_timeout=0with concurrentopencode runworkers; includes a detailed root-cause analysis and a suggested fixdatabase is lockederror when running multiple concurrent sessionsGaryGong27 commentedon Jul 10, 2026
Also reproducible in the interactive TUI (not just headless
run), on opencode 1.17.15–1.17.18, macOS (Apple Silicon) + Linux: when the sharedopencode.dbis locked at boot, the TUI renders a blank screen with no visible error — the failure only appears in~/.local/share/opencode/log/*.log:around
InstanceStore.boot/Project.fromDirectory(the startup upsert intoproject).The affected instance never renders, and in the interactive case there's no actionable message and (in some paths) no non-zero exit — users can't tell "failed" from "hung," so diagnosis is slow.
Ask: surface a fatal, user-visible DB error (and exit non-zero) that names the contended DB path and suggests closing other instances, instead of a blank TUI. Happy to help repro.
emberDesire commentedon Sep 2, 2026
Additional Windows reproduction on OpenCode 1.18.25 confirming this is still present, plus a recovery path that preserved all existing session/chat history.
Environment
Several concurrent runs began hitting
LockTimeoutError/SQLiteError: database is lockedduring session/message writes. After that, every new OpenCode invocation failed during startup inProject.fromDirectory()while attempting the sharedprojectupsert.The CLI only surfaced:
The failure reproduced from the project directory, the user home directory, and a fresh temp directory, confirming that it was shared/global OpenCode state rather than project configuration.
Important recovery finding: a lingering OpenCode process was still holding the database. Terminating that process immediately restored normal OpenCode startup. We did not delete
opencode.db, the WAL, or any OpenCode state, so all existing session/chat history was preserved.This seems worth making part of the recovery path because users encountering a persistent DB lock may otherwise follow advice to delete/reset the database and unnecessarily lose their history.
Also, OpenCode 1.18.25 already sets:
so the busy timeout alone does not prevent this failure mode.
A useful recovery flow could be:
Unexpected server error.Project.fromDirectory()and only report recovery once startup succeeds.I would not auto-kill another OpenCode process by default, since it may still be doing useful work. But an explicit terminate → verify exit → verify DB unlock → retry flow would make this recoverable while protecting users from unnecessarily deleting their chat history.
thdxr commentedon Oct 11, 2026
Thanks for the report! OpenCode 2.0 is now out and development is focused on V2, so we're closing issues filed against OpenCode 1. Please upgrade (
opencode upgrade --major, details: https://anoma.ly/notes/opencode-2-0), and if this is still relevant on 2.0, reopen this issue or open a new one with your 2.0 version.— from 𝕺𝖕𝖊𝖓𝕮𝖔𝖉𝖊