Skip to content

[Bug]: Driver 'codex' failed to create instance: Cannot create Codex shadow home entry '.sqlite-maintenance.lock' #15138

Description

@rajiitmandi21

Before submitting

  • I searched existing issues and did not find a duplicate.
  • I included enough detail to reproduce or investigate the problem.

Area

apps/server

Steps to reproduce

  1. Configure multiple Codex accounts using the multi-account layout: one primary shared homePath (e.g. ~/.codex) and additional provider instances with a shadowHomePath (e.g. ~/.codex-t3/cw-prem).
  2. Run active sessions using the shadow-home Codex account.
  3. During execution or session completion, Codex CLI / SQLite maintenance creates .sqlite-maintenance.lock as a standalone regular file (0-byte lock file) in the shadow home directory.
  4. Restart T3 Code (or restart after an app update).
  5. During startup, T3 Code runs materializeCodexShadowHome and encounters the non-symlink .sqlite-maintenance.lock.

Expected behavior

T3 Code should handle .sqlite-maintenance.lock gracefully (e.g. treating SQLite lock / maintenance files as replaceable runtime files, part of SQLite file families, or shadow-local) instead of aborting provider initialization and disabling the entire account.

Actual behavior

The provider instance fails to create and is disabled:

Driver 'codex' failed to create instance: Cannot create Codex shadow home entry '.sqlite-maintenance.lock' because '/Users/<user>/.codex-t3/<account>/.sqlite-maintenance.lock' already exists and is not a symlink.

Impact

Blocks work completely (the affected Codex account is marked Disabled and cannot be used until manually resolved).

Version or commit

T3 Code (Alpha) 0.0.45

Environment

  • macOS 27.0 (Apple Silicon arm64)
  • T3 Code (Alpha) 0.0.45
  • codex-cli 0.160.0

Logs or stack traces

Driver 'codex' failed to create instance: Cannot create Codex shadow home entry '.sqlite-maintenance.lock' because '/Users/<user>/.codex-t3/<account>/.sqlite-maintenance.lock' already exists and is not a symlink.

File inspection on affected vs working shadow profiles:

Affected shadow home:

$ ls -la ~/.codex-t3/<account>/.sqlite-maintenance.lock
-rw-r--r--@ 1 user staff 0 Oct 3 14:51 .sqlite-maintenance.lock

Working shadow home:

$ ls -la ~/.codex-t3/<working-account>/.sqlite-maintenance.lock
lrwxr-xr-x 1 user staff 42 Oct 3 15:32 .sqlite-maintenance.lock -> /Users/<user>/.codex/.sqlite-maintenance.lock

Related: Similar to the SQLite file family divergence discussed in #5817 / PR #7201, but specifically triggered by .sqlite-maintenance.lock.

Workaround

Remove the standalone lock file from the shadow home (or recreate the symlink to ~/.codex/.sqlite-maintenance.lock):

rm ~/.codex-t3/<account>/.sqlite-maintenance.lock
ln -s ~/.codex/.sqlite-maintenance.lock ~/.codex-t3/<account>/.sqlite-maintenance.lock

After doing this, reloading or restarting T3 Code allows the account instance to initialize cleanly.

Activity

  1. juliusmarminge commented on Oct 3, 2026

    @juliusmarminge
    Member

    Note

    Grok responding on behalf of Julius.

    Triage

    Thanks @rajiitmandi21 for the clear report and for comparing the affected and working shadow homes! I confirmed this on v0.0.45 and on current main (263097a8). CodexHomeLayout hasn't changed between them, so a newer build won't avoid this. It's the same kind of startup failure as #5817 (open), but .sqlite-maintenance.lock isn't a SQLite database file, so I'm keeping this open as its own issue.

    What happens

    Auth-overlay accounts run Codex with CODEX_HOME set to the shadow home. T3 doesn't set CODEX_SQLITE_HOME, so the shadow directory is also Codex's SQLite home. In Codex 0.160.0, the reclamation worker creates <sqlite home>/.sqlite-maintenance.lock and takes an advisory lock on it (try_ownership in reclamation.rs at rust-v0.160.0). The file is empty and holds no database contents.

    On the next startup, materializeCodexShadowHome symlinks every shared-home entry that isn't private (auth.json, models_cache.json) or shadow-local (log, memories, tmp). This lock file isn't in either set. When the shadow copy is already a regular file, ensureSymlink raises CodexShadowHomeEntryConflictError and the provider gets disabled. Today the only entry that can be replaced is the mcp-oauth-locks directory.

    The symlink on your working account is the layout T3 is trying to create, and it's the right one. The lock elects a single reclamation worker per SQLite home, and these accounts already share the SQLite databases through symlinks. A separate lock file in each shadow home would let two workers reclaim the same databases. Replacing the 0-byte shadow file doesn't throw away any session or SQLite data.

    Likely fix area

    When .sqlite-maintenance.lock in the shadow home is a regular file, replace it with a symlink to the shared home's lock, the same way mcp-oauth-locks is handled, and let provider startup continue. A fix that only special-cases *.sqlite, -wal, and -shm (like the closed, unmerged #7201 and #9229 for #5817) wouldn't cover this filename. A maintainer will decide on the fix direction.

    Workaround

    Your workaround is the right recovery. Stop any Codex processes that might hold the lock, remove the regular file from the shadow home, and symlink it to the shared lock. Then restart T3. Don't delete auth.json or any *.sqlite files.

  2. added
    bugSomething is broken or behaving incorrectly.
    via-triageFiled through npx t3 triage
    on Oct 3, 2026
  3. WhiteWarrior625 commented on Oct 3, 2026

    @WhiteWarrior625

    Confirmed on Linux x86_64 with T3 Code Nightly 0.0.46-nightly.20261003.2632, build commit f391794a35c604d57e166a3ab48d56fc6e4e469a, and codex-cli 0.160.0.

    The second Codex instance uses the documented shared-home plus shadow-home layout. Its persisted provider configuration has enabled: true. Both <shared-home>/.sqlite-maintenance.lock and <shadow-home>/.sqlite-maintenance.lock are regular zero-byte files.

    The live provider catalog reports:

    Driver 'codex' failed to create instance: Cannot create Codex shadow home entry '.sqlite-maintenance.lock' because '<shadow-home>/.sqlite-maintenance.lock' already exists and is not a symlink.
    

    The account has no registered adapter or available models after this failure. The primary Codex account remains available.

    There is also a misleading UI symptom worth covering in the fix: the model picker says "Disabled in settings" for the affected account even though it is enabled in the settings file. Upstream's buildUnavailableProviderSnapshot sets enabled: false and installed: false for the failed instance. ModelPickerSidebar checks that flag before displaying the initialization error, hiding the actual failure behind a settings label.

    This reproduces the lock-file conflict on the current nightly and confirms that the secondary account can look deliberately disabled when provider creation actually failed.

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

    bugSomething is broken or behaving incorrectly.via-triageFiled through npx t3 triage

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions