[CLI] Make thread writer lock directory configurable and locking optional for shared CODEX_HOME

Open 💬 2 comments Opened Aug 12, 2026 by fengxin-zhxx

What version of Codex CLI is running?

codex-cli 0.147.0

What subscription do you have?

Pro 20x

Which model were you using?

gpt-5.6-sol

What platform is your computer?

Linux x86_64

What terminal emulator and version are you using (if applicable)?

tmux Bash 5.2

Codex doctor report

What issue are you seeing?

My CODEX_HOME is stored on a shared NAS because the configuration and session history need to be accessible from multiple machines. However, runtime writer lock files need to be host-local in this deployment. In some workflows I also intentionally need different hosts to be able to open and write the same thread, accepting the associated consistency risk.

In Codex CLI 0.147.0, the thread store unconditionally places writer locks under CODEX_HOME:

const WRITER_LOCK_DIR: &str = "thread-writer-locks";

directory: codex_home.join(WRITER_LOCK_DIR),

There is currently no config.toml setting to:

  1. place these files in a host-local runtime directory; or
  2. explicitly disable thread writer locking.

Codex therefore always attempts to create and lock:

<CODEX_HOME>/thread-writer-locks/.coordination.lock
<CODEX_HOME>/thread-writer-locks/<thread-id>.lock

On a shared/NAS-backed CODEX_HOME where runtime lock files cannot or should not be stored, creating or resuming a thread fails or requires an out-of-band symlink workaround.

Observed error, with local paths and thread IDs redacted:

Error: Failed to start a fresh session through the app server: thread/start failed during TUI bootstrap: thread/start failed: error creating thread: Fatal error: Failed to initialize session: thread-store internal error: failed to create thread writer lock directory XX: File exists (os error 17) (code -32603)

The current workaround is to make <CODEX_HOME>/thread-writer-locks a symlink to a host-local path such as /tmp/codex-thread-writer-locks. This is fragile because the shared symlink has to be managed outside Codex. Deleting and recreating it from shell startup fi les also races with other shells, hosts, and running Codex processes.

What steps can reproduce the bug?

  1. Mount the same shared NAS directory on host A and host B.
  2. Configure both hosts with a shared CODEX_HOME and host-local SQLite state:
export CODEX_HOME="<shared-nas>/codex-home"
export CODEX_SQLITE_HOME="<host-local>/codex-sqlite"
  1. Start Codex and create or resume a thread:

codex resume <redacted-thread-id>

  1. Codex unconditionally attempts to create and lock files under:

<shared-nas>/codex-home/thread-writer-locks

  1. There is no supported configuration for moving only these lock files to

host-local storage or disabling the lock.

  1. A symlink to a host-local directory can work around the path restriction, but managing that shared symlink from .bashrc is race-prone when multiple machines use the same CODEX_HOME.

What is the expected behavior?

The current locking behavior should remain the default, but advanced deployments
should be able to configure it explicitly in config.toml.

For example:

# Defaults to true.
thread_writer_lock_enabled = true

# Defaults to "$CODEX_HOME/thread-writer-locks".
thread_writer_lock_dir = "/local/runtime/codex/thread-writer-locks"

When thread_writer_lock_dir is set, both the coordination lock and per-thread lock files should be created in that directory instead of under CODEX_HOME.

It should also be possible to opt out explicitly:

thread_writer_lock_enabled = false

When disabled, Codex should not create, acquire, inspect, clean up, or delete thread writer lock files.

Disabling the lock or using separate host-local lock directories removes cross-host single-writer protection. This is intentional for this use case, should be opt-in, and can be documented with an appropriate warning. The
default behavior should remain unchanged.

Additional information

The path is currently hard-coded here:

https://github.com/openai/codex/blob/4ef836f883c38ba6d39e6920f335ce6452b7de33/codex-rs/thread-store/src/local/writer_lock.rs#L17-L35

Codex already supports separating SQLite runtime state from CODEX_HOME
through sqlite_home / CODEX_SQLITE_HOME, but the thread writer lock
directory has no equivalent configuration:

https://github.com/openai/codex/blob/4ef836f883c38ba6d39e6920f335ce6452b7de33/codex-rs/config/src/config_toml.rs#L320-L327

I searched existing issues before submitting. The following issues are related to writer ownership but do not cover configurable or optional writer locking for shared/NAS-backed CODEX_HOME:

View original on GitHub ↗

2 Comments

jdcodes1 · 9 days ago

Two supporting notes for this request. First, on NAS deployments the current design can be worse than either of your proposed options: advisory file locks over NFS/SMB are semantically unreliable (silently non-enforcing on some mounts, spurious ENOLCK/hangs on others), so the one thing the unconditional $CODEX_HOME/thread-writer-locks/ placement guarantees on a network share is the failure modes, not the exclusion (https://github.com/openai/codex/blob/1f41cc5d92/codex-rs/thread-store/src/local/writer_lock.rs#L17-L34). A host-local runtime dir ($XDG_RUNTIME_DIR-style default with a writer_lock_dir override) fixes that independently of the multi-writer question.

Second, the "explicitly disable locking" half has more demand than this issue alone: the same single-writer constraint is what blocks Remote Control from attaching to a live CLI session (#37967), post-/fork resume from another terminal (#38144, #38297), and produces empty two-instance replays (#37987). A per-thread read-only attach that skips the writer lock would satisfy several of those without accepting full concurrent-writer risk — worth designing the config knob so "shared read, single write" is expressible, not just on/off.

suiuko · 7 days ago

I would like to know when the repair will be carried out. Currently, version 0.147.0 makes it very difficult to achieve cross-device development.