Skip to content

Desktop (macOS): "failed to initialize sqlite state runtime" when another Codex app-server holds logs_2.sqlite (not corruption, not size) #30105

Open

Description

@BryanTegomoh

Summary

On native macOS, Codex Desktop fails to launch with the blocking dialog "Codex cannot access its local database" / failed to initialize sqlite state runtime under ~/.codex. The trigger is concurrent access: a second Codex app-server (a Codex IDE extension, an older build) was holding ~/.codex/logs_2.sqlite open, which prevented the Desktop app-server from initializing the SQLite state runtime within the startup handshake.

Both state_5.sqlite and logs_2.sqlite pass PRAGMA integrity_check (ok) and initialize fine in isolation — so this is neither corruption nor (purely) size. This is likely the same underlying cause as #27741 and #28666, but observed on native macOS and pinpointing multi-client / shared-CODEX_HOME concurrency as the trigger.

Environment

  • Codex Desktop for macOS, version 26.623.30605 (build 4415)
  • Bundled codex-cli 0.142.2
  • macOS 26.5.1, Apple Silicon (arm64)
  • Default ~/.codex on the internal APFS volume (not WSL, no /mnt/network mount)
  • Several Codex clients run against the same ~/.codex (Desktop app, Codex IDE extensions, and the codex CLI), each spawning its own ephemeral app-server (the app-server daemon is not enabled)

User-visible failure

Codex cannot access its local database.
...
Error: (code=1, signal=null).
Most recent error: Error: failed to initialize sqlite state runtime under
~/.codex: failed to initialize state runtime at ~/.codex

Desktop logs show the handshake child exiting code=1 repeatedly, ~5–8 s per attempt:

initialize_handshake_result durationMs=7308 ... outcome=failure
reason="Error: failed to initialize sqlite state runtime under ~/.codex: failed to initialize state runtime at ~/.codex"

One internal tracing line surfaced during a failed init: WARN ... slow statement: execution time exceeded alert threshold.

Root cause (reproduced)

  1. lsof ~/.codex/logs_2.sqlite showed another Codex app-server (a Codex IDE extension's, an older build) holding it (+ -wal, -shm) open continuously. state_5.sqlite had no holders.
  2. Driving the bundled app-server directly reproduces it:
    printf '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{...}}\n' | CODEX_HOME=~/.codex codex app-server → exits 1 with the same error.
  3. Bisection (all on codex-cli 0.142.2):
    • Fresh empty CODEX_HOME → init succeeds
    • Fresh home + real state_5.sqlite (170 MB) → succeeds
    • Fresh home + real logs_2.sqlite (1.14 GB) → succeeds (init < 10 s)
    • All four real DBs together + real config.toml → succeeds
    • Real ~/.codex while another app-server holds logs_2.sqlite → fails
    • Kill that app-server (freeing logs_2.sqlite), retry against real ~/.codex → succeeds (durationMs ≈ 450)
  4. PRAGMA integrity_check on both state_5.sqlite and logs_2.sqlite = ok.

So the state DBs are healthy; the Desktop app-server simply cannot acquire the access it needs to logs_2.sqlite during init while another (often older-version) app-server holds it, and the init aborts within the startup handshake budget.

Impact

Desktop refuses to launch entirely whenever another Codex client (IDE extension / CLI / another app-server) happens to be running against the same ~/.codex. The dialog advises "Close other Codex applications," but it is not obvious that a background IDE-extension app-server counts, and the heavier "Back Up and Rebuild" is unnecessary because the DB is fine.

Workaround

Free logs_2.sqlite instead of rebuilding:

lsof ~/.codex/logs_2.sqlite     # find the holding app-server PID(s)
kill <pid>                      # stop them
# relaunch Desktop

No data is moved or lost.

Suggestions

  1. Tolerate concurrent app-servers. The state runtime should coexist with other app-servers (shared WAL readers, or coordinate via the app-server daemon / single-writer with graceful waiting) instead of aborting the Desktop handshake.
  2. Surface the leaf cause. On macOS the error collapsed to a generic "failed to initialize state runtime at ~/.codex" with no underlying SQLite error (contrast error returnedfrom database: (code: 5) database is locked #28666, which shows (code: 5) database is locked). Including the underlying SQLite/sqlx error (busy / locked / pool timeout) in the dialog and logs would make this self-diagnosable.
  3. Targeted recovery. When only logs_2.sqlite is the blocker, offer a "retry after releasing the logs DB" / recreate-just-the-logs-DB path (cf. remote-control should recover from a corrupt logs_2.sqlite instead of failing readiness #24001) rather than the full Back Up and Rebuild.

Related: #27741, #28666, #24006, #24001, #21750.

Activity

  1. added
    bugSomething isn't working
    appIssues related to the Codex desktop app
    app-serverIssues involving app server protocol or interfaces
    on Jun 25, 2026
  2. github-actions commented on Jun 25, 2026

    @github-actions
    Contributor

    Potential duplicates detected. Please review them and close your issue if it is a duplicate.

    Powered by Codex Action

  3. BryanTegomoh commented on Jun 26, 2026

    @BryanTegomoh
    Author

    Not a duplicate of #28666: that report is WSL (\\wsl.localhost\Ubuntu-22.04\..., runCodexInWindowsSubsystemForLinux = true). This is native macOS on APFS, no WSL, default ~/.codex. It does look like the same underlying bug as #27741, #28666, and #24001, so here is what narrows it.

    Root cause: logs_2.sqlite is a diagnostic log store, but it sits on the critical launch path. When state-runtime init cannot get a connection from the logs_2 pool within the startup handshake, the whole app hard-fails with "Codex cannot access its local database." Two independent conditions cause that acquire failure:

    Evidence (macOS, Desktop 26.623.30605 / codex-cli 0.142.2):

    • PRAGMA integrity_check on state_5.sqlite and logs_2.sqlite both return ok, so this is not corruption.
    • lsof ~/.codex/logs_2.sqlite showed a second (older-build) Codex app-server holding it; Desktop init then failed code=1 after ~7s on every attempt.
    • Releasing that holder makes Desktop init succeed in ~450ms, with nothing else changed.
    • The same 1.14 GB logs_2 initializes fine for a single client in isolation, so the trigger is contention, not the file.

    Workaround without data loss (better than "Back Up and Rebuild"):

    lsof ~/.codex/logs_2.sqlite   # find the holding app-server PID(s)
    kill <pid>                    # then relaunch Desktop
    

    Suggested fix: take logs_2 off the critical launch path. It is diagnostics, so its init should be lazy and non-fatal, degrading logging instead of blocking launch (aligns with #24001). If it must init at startup, set busy_timeout and raise the pool-acquire budget. Also surface the leaf error: on macOS the dialog collapses to a generic message with no cause, unlike #28666 and #27741.

    Happy to send a full RUST_LOG trace or test a patch.

  4. Nicolas0315 commented on Jun 26, 2026

    @Nicolas0315

    I pushed a candidate fix here:

    https://github.com/openai/codex/compare/main...Nicolas0315:codex/logs-db-nonfatal-fallback?expand=1

    What changed:

    • StateRuntime now treats logs_2.sqlite lock/busy failures as non-fatal during startup.
    • On that specific failure mode, it records codex.sqlite.fallback.count and uses a single-connection in-memory logs DB for the current process, so existing log insert/query APIs still work.
    • State/goals/memories DB failures still abort startup, and corrupt logs DB recovery is still surfaced for CLI recovery instead of being treated as a lock.

    Local validation on 08aaf33d1:

    • just fmt
    • git diff --check
    • cargo test --manifest-path codex-rs\Cargo.toml -p codex-state init_uses_ephemeral_logs_db_when_disk_logs_db_is_locked -- --nocapture
    • cargo test --manifest-path codex-rs\Cargo.toml -p codex-tui embedded_state_db_corruption_preserves_failed_database_for_cli_recovery -- --nocapture
    • cargo test --manifest-path codex-rs\Cargo.toml -p codex-state -- --nocapture
    • cargo check --manifest-path codex-rs\Cargo.toml -p codex-state -p codex-tui -p codex-app-server

    SSH validation:

    • cyberagent-mac-m5max: fetched 08aaf33d1; git diff --check HEAD~1 HEAD OK; focused lock regression OK; cargo check OK.
    • nicolas2025: fetched 08aaf33d1; diff check OK; focused lock regression OK; cargo check OK; no lingering cargo/rustc/link processes afterward.
    • nicolas-macbook-pro: fetched 08aaf33d1; diff check OK; no cargo installed, so diff-only.
    • rtx5060ti: fetched 08aaf33d1; diff check OK; cargo is blocked by the host's existing link.exe toolchain issue (link: extra operand ..., exit 101); no lingering cargo processes afterward.
  5. boombx403-byte commented on Aug 18, 2026

    @boombx403-byte

    Hi @BryanTegomoh, cross-platform WSL/Windows path mismatches often make healthy transcripts look broken when workspace contexts change. Codex Rescue Alpha5 explicitly separates transcript integrity from workspace path-family portability without rewriting saved paths.

    If you'd like to check the local rollout safely:

    pip install codex-rescue==0.1.0a5
    codex-rescue doctor --latest

    Please sanitize private paths before posting any output.

  6. BryanTegomoh commented on Aug 23, 2026

    @BryanTegomoh
    Author

    Update: I can no longer reproduce this on Desktop 26.818.41509 with bundled codex-cli 0.149.0-alpha.4.1. Two app-server processes are currently sharing ~/.codex/logs_2.sqlite, including one started while the other was already running.

    #33938 added consistent WAL settings and a five-second busy timeout after this report, which appears to have mitigated the observed case. Current main still aborts startup if logs DB initialization ultimately fails, so the non-fatal fallback remains unresolved.

    @anp-oai, was #33938 intended to resolve this case? If so, I am fine closing this unless it recurs.

  7. 1328837476-hug commented on Aug 27, 2026

    @1328837476-hug

    Root-cause analysis + one-line fix suggestion for the un-actionable failed to initialize sqlite state runtime error (cross-posting this analysis here because it applies to every sqlite state-runtime init failure report, including #30105, #39015, #32160; hit it while debugging the Windows desktop startup chain in #40752)

    While debugging a machine where the desktop app failed to start, the app-server surfaced:

    Error: failed to initialize sqlite state runtime under C:\Users\<user>\.codex:
    failed to initialize state runtime at C:\Users\<user>\.codex
    

    Neither layer names the failing database or the underlying sqlite error, even though the code already has all of it:

    • codex-rs/state/src/runtime/recovery.rs defines RuntimeDbInitError { label, operation, path, source } with Display failed to {operation} {label} at {path}: {source} — exactly the information needed
    • codex-rs/rollout/src/state_db.rs wraps it with .with_context("failed to initialize state runtime at {home}") — chain preserved
    • codex-rs/app-server/src/lib.rs (both sqlite-init failure paths, ~line 609 and ~1254) formats with format!("... {err}") — and the plain anyhow Display prints only the outermost context, silently dropping the RuntimeDbInitError layer below it

    So users see the two generic outer layers and none of the specifics (which DB of the six, open vs migrate, which path, which sqlite error code). On the machine I debugged, the actual failure was a schema-level state_5.sqlite incompatibility — integrity_check: ok, all _sqlx_migrations rows success=1 — and pinning it down required manually bisecting all six *.sqlite files out of ~/.codex.

    Suggested fix (two characters per site)

    - "failed to initialize sqlite state runtime under {}: {err}",
    + "failed to initialize sqlite state runtime under {}: {err:#}",

    (also the sibling site in init_sqlite_state_db_with_fresh_start_on_corruption). The {err:#} alternate form appends the full Caused by: chain — the same pattern rollout/src/state_db.rs already uses in emit_startup_warning(&format!("failed to initialize state runtime: {err:#}")). With it, the same failure becomes immediately diagnosable:

    Error: failed to initialize sqlite state runtime under C:\Users\<user>\.codex:
    failed to initialize state runtime at C:\Users\<user>\.codex:
    failed to open state DB at C:\Users\<user>\.codex\state_5.sqlite:
    error returned from database: (code: 26) file is not a database
    

    A regression test could assert that format!("{err:#}") for an init failure on a garbage state DB contains "failed to open state DB" and the DB path (the existing runtime_db_path_for_corruption_error_returns_failed_database_path test in codex-rs/state/src/runtime/recovery_tests.rs already shows how to construct that failure).

    Happy to provide the full patch if useful — per docs/contributing.md I'm keeping it as an issue analysis rather than a PR.

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    appIssues related to the Codex desktop appapp-serverIssues involving app server protocol or interfacesbugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions