Skip to content

Concurrent opencode run workers can fail at startup with database is locked #33320

Closed as not planned

Description

@coygeek

Description

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

  1. Configure an OpenAI-compatible provider/model. In my reproduction, the model was openrouter/cohere/north-mini-code:free.
  2. Launch multiple headless workers close together from the same OS user account:
for worker in 1 2 3; do
  (
    OPENCODE_CONFIG_DIR="$generated_config_dir" \
      opencode run \
        --dangerously-skip-permissions \
        -m openrouter/cohere/north-mini-code:free \
        --title "worker-$worker" \
        "Execute the attached worker prompt." \
        --file "$prompt_path"
  ) &
done
wait
  1. One worker can exit immediately with:
Error: Unexpected error

database is locked
  1. 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.

Activity

  1. github-actions commented on Jun 22, 2026

    @github-actions
    Contributor

    This issue might be a duplicate of existing issues. Please check:

  2. GaryGong27 commented on Jul 10, 2026

    @GaryGong27

    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.

  3. emberDesire commented on Sep 2, 2026

    @emberDesire

    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:

    1. Retry transient lock failures with bounded backoff.
    2. If still locked, expose the actual SQLite lock error and DB path rather than only Unexpected server error.
    3. Detect likely OpenCode processes that may still hold the shared DB and show their PID/command line.
    4. In interactive mode, offer an explicit user-confirmed option to terminate selected OpenCode processes.
    5. Verify the selected process actually exited.
    6. Verify the database is no longer locked/writable.
    7. 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.

  4. thdxr commented on Oct 11, 2026

    @thdxr
    Member

    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 𝕺𝖕𝖊𝖓𝕮𝖔𝖉𝖊

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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