Client or integration
Codex App
Area
CLI
Summary
ocx sync refuses the Codex config injection with the generic history_injection_preflight_unavailable whenever the Codex state database (~/.codex/state_5.sqlite) is in WAL journal mode with no live writer connected (no -shm/-wal sidecar files present). In that state a read-only SQLite connection cannot initialize WAL shared memory, so new Database(resolvedPath, { readonly: true }) inside preflightCodexHistoryInjection throws SQLITE_CANTOPEN (14), which the catch-all in src/codex/inject.ts (historyPreflight) folds into the generic "preflight unavailable" refusal.
Expected: the preflight should still be able to inspect the store — immutable=1 reads work fine and the preflight only runs PRAGMA table_info(threads) plus a SELECT rollout_path, history_mode FROM threads, so a lock-free read is safe — or at minimum report a distinct failure reason so operators can tell "store is fine, preflight could not open it read-only" apart from a genuinely unreadable store. The store itself is healthy; the refusal blocks model_catalog_json from reaching config.toml on every sync attempt until a workaround is applied.
Reproduction
- macOS + ChatGPT desktop (Codex) used at least once, so
~/.codex/state_5.sqlite exists; quit the app cleanly (sidecar -wal/-shm are removed on clean close; verify with ls ~/.codex/state_5.sqlite*).
- Confirm the store is WAL and readable without locks:
sqlite3 "file:$HOME/.codex/state_5.sqlite?immutable=1" "PRAGMA journal_mode; SELECT COUNT(*) FROM threads;" → wal, row count (store healthy)
sqlite3 "file:$HOME/.codex/state_5.sqlite?mode=ro" "SELECT COUNT(*) FROM threads" → Error: in prepare, unable to open database file (14) ← the exact condition the preflight hits
- Run
ocx sync.
- Observe the refusal (logs below);
Codex sync did not complete and config.toml keeps the previous model_catalog_json (no damage, but the transition never converges).
Workaround we currently use: hold one read-write connection open for the duration of the sync (e.g. Python sqlite3.connect(path) kept alive while ocx sync runs, then close). The -shm then exists, the read-only preflight joins it, and sync completes normally (rc=0, + 440 models appended to Codex catalog). This suggests a targeted fix inside the preflight would work: on SQLITE_CANTOPEN for a WAL store, retry with immutable=1 (or open briefly read-write to create the shared memory), or surface a dedicated reason code instead of the generic one.
Code pointers (2.58.0): src/codex/history-provider.ts preflightCodexHistoryInjection() — db = new Database(resolvedPath, { readonly: true }); src/codex/inject.ts historyPreflight() — catch { return "history_injection_preflight_unavailable"; }.
Version
2.58.0
Operating system
macOS 26 (Tahoe) 25.6, Apple Silicon (arm64)
Provider and model
Not provider-specific (Codex state store access).
Logs or error output
$ ocx sync
Codex config injection refused: history_injection_preflight_unavailable. Existing provider definitions and conversation files were preserved. Paginated history requires native-writer coordination; do not run legacy recovery or retry this transition blindly.
Target Codex home: /Users/[USER]/.codex
Codex sync did not complete. Fix the reported Codex config issue and retry.
$ sqlite3 "file:$HOME/.codex/state_5.sqlite?mode=ro" "SELECT COUNT(*) FROM threads"
Error: in prepare, unable to open database file (14)
$ sqlite3 "file:$HOME/.codex/state_5.sqlite?immutable=1" "PRAGMA journal_mode; SELECT COUNT(*) FROM threads;"
wal
2465
Redacted configuration
Not config-dependent; environment facts: ocx 2.58.0, codex-cli 0.154.0 (source=configured), CODEX_HOME=/Users/[USER]/.codex, state store state_5.sqlite (valid SQLite format 3 header, threads table present with 2465 rows).
Client or integration
Codex App
Area
CLI
Summary
ocx syncrefuses the Codex config injection with the generichistory_injection_preflight_unavailablewhenever the Codex state database (~/.codex/state_5.sqlite) is in WAL journal mode with no live writer connected (no-shm/-walsidecar files present). In that state a read-only SQLite connection cannot initialize WAL shared memory, sonew Database(resolvedPath, { readonly: true })insidepreflightCodexHistoryInjectionthrowsSQLITE_CANTOPEN(14), which the catch-all insrc/codex/inject.ts(historyPreflight) folds into the generic "preflight unavailable" refusal.Expected: the preflight should still be able to inspect the store —
immutable=1reads work fine and the preflight only runsPRAGMA table_info(threads)plus aSELECT rollout_path, history_mode FROM threads, so a lock-free read is safe — or at minimum report a distinct failure reason so operators can tell "store is fine, preflight could not open it read-only" apart from a genuinely unreadable store. The store itself is healthy; the refusal blocksmodel_catalog_jsonfrom reachingconfig.tomlon every sync attempt until a workaround is applied.Reproduction
~/.codex/state_5.sqliteexists; quit the app cleanly (sidecar-wal/-shmare removed on clean close; verify withls ~/.codex/state_5.sqlite*).sqlite3 "file:$HOME/.codex/state_5.sqlite?immutable=1" "PRAGMA journal_mode; SELECT COUNT(*) FROM threads;"→wal, row count (store healthy)sqlite3 "file:$HOME/.codex/state_5.sqlite?mode=ro" "SELECT COUNT(*) FROM threads"→Error: in prepare, unable to open database file (14)← the exact condition the preflight hitsocx sync.Codex sync did not completeandconfig.tomlkeeps the previousmodel_catalog_json(no damage, but the transition never converges).Workaround we currently use: hold one read-write connection open for the duration of the sync (e.g. Python
sqlite3.connect(path)kept alive whileocx syncruns, then close). The-shmthen exists, the read-only preflight joins it, and sync completes normally (rc=0,+ 440 models appended to Codex catalog). This suggests a targeted fix inside the preflight would work: onSQLITE_CANTOPENfor a WAL store, retry withimmutable=1(or open briefly read-write to create the shared memory), or surface a dedicated reason code instead of the generic one.Code pointers (2.58.0):
src/codex/history-provider.tspreflightCodexHistoryInjection()—db = new Database(resolvedPath, { readonly: true });src/codex/inject.tshistoryPreflight()—catch { return "history_injection_preflight_unavailable"; }.Version
2.58.0
Operating system
macOS 26 (Tahoe) 25.6, Apple Silicon (arm64)
Provider and model
Not provider-specific (Codex state store access).
Logs or error output
Redacted configuration
Not config-dependent; environment facts:
ocx 2.58.0, codex-cli 0.154.0 (source=configured),CODEX_HOME=/Users/[USER]/.codex, state storestate_5.sqlite(validSQLite format 3header,threadstable present with 2465 rows).