What issue are you seeing?
When using the experimental app-server API as a third-party client, thread/resume can reject a running thread if the requested rollout path and the active rollout path refer to the same file through different symlink spellings.
The failure happens in the running-thread resume path when params.path is provided. The current check compares the two PathBuf values literally:
requested_path != active_path
On machines where the home directory is a symlink, one path can use the symlinked home while the other uses the resolved real path. These paths point to the same rollout JSONL, but app-server treats them as different and returns:
cannot resume running thread <thread-id> with stale path: requested `<symlink-home>/.../rollout-<id>.jsonl`, active `<real-home>/.../rollout-<id>.jsonl`
This blocks third-party clients that rely on experimental thread/resume with path.
What steps can reproduce the bug?
- Run Codex app-server with experimental API enabled.
- Use an environment where the user home directory is a symlink, for example:
/home/user resolves to /mnt/users/user
- or
/Users/user resolves through another mounted path
- Start or resume a thread so app-server has a running thread with an active rollout path.
- Call
thread/resume for that same running thread with params.path set to the rollout JSONL path using the symlinked home spelling.
- Observe that app-server compares the requested path and active rollout path literally and rejects the request as
stale path, even though both paths resolve to the same file.
A downstream workaround was to temporarily disable this stale-path check, but the proper upstream fix should preserve the stale-path protection while comparing normalized/canonicalized paths, or otherwise using a path identity check that treats equivalent symlinked paths as the same file.
What is the expected behavior?
thread/resume should allow resuming a running thread when params.path and the active rollout path resolve to the same file.
It should still reject genuinely stale paths that point to a different rollout/thread.
Additional information
This appears related to the broader class of path identity issues reported in #18483, #20317, and #20882, but the trigger here is narrower: the app-server v2 experimental thread/resume running-thread path check rejects equivalent symlinked paths before the client can resume.
Environment observed downstream:
- Codex CLI/app-server version:
0.130.0
- Platform:
Darwin 24.6.0 arm64 arm
- Scenario: third-party app-server client, experimental API enabled
- Home directory is symlinked on internal remote machines
What issue are you seeing?
When using the experimental app-server API as a third-party client,
thread/resumecan reject a running thread if the requested rollout path and the active rollout path refer to the same file through different symlink spellings.The failure happens in the running-thread resume path when
params.pathis provided. The current check compares the twoPathBufvalues literally:requested_path != active_pathOn machines where the home directory is a symlink, one path can use the symlinked home while the other uses the resolved real path. These paths point to the same rollout JSONL, but app-server treats them as different and returns:
This blocks third-party clients that rely on experimental
thread/resumewithpath.What steps can reproduce the bug?
/home/userresolves to/mnt/users/user/Users/userresolves through another mounted paththread/resumefor that same running thread withparams.pathset to the rollout JSONL path using the symlinked home spelling.stale path, even though both paths resolve to the same file.A downstream workaround was to temporarily disable this stale-path check, but the proper upstream fix should preserve the stale-path protection while comparing normalized/canonicalized paths, or otherwise using a path identity check that treats equivalent symlinked paths as the same file.
What is the expected behavior?
thread/resumeshould allow resuming a running thread whenparams.pathand the active rollout path resolve to the same file.It should still reject genuinely stale paths that point to a different rollout/thread.
Additional information
This appears related to the broader class of path identity issues reported in
#18483,#20317, and#20882, but the trigger here is narrower: the app-server v2 experimentalthread/resumerunning-thread path check rejects equivalent symlinked paths before the client can resume.Environment observed downstream:
0.130.0Darwin 24.6.0 arm64 arm