Codex App local handoff leaves task CWD index stale and blocks managed worktree
What version of the Codex App are you using?
- Codex App:
26.715.21425(CFBundleVersion=5488) - Bundled CLI:
codex-cli 0.145.0-alpha.18
What subscription do you have?
Not relevant to the local worktree failure.
What platform is your computer?
macOS, local execution host. The Codex home directory is symlinked from $HOME/.codex to an external volume.
What issue are you seeing?
After using Hand off to move a local task from its primary checkout to a Codex-managed worktree, the new task is blocked by:
Couldn't check worktree status
Retry to verify this chat's working directory
Retrying and restarting the app do not clear the error.
The Git worktree itself is healthy: it exists, is registered by git worktree list, is on the requested new branch, has a valid linked Git directory, is clean, and passes a Git integrity check.
The handoff appears to finish its core operations. Sanitized Desktop logs show:
- the source task was forked;
- the new task was assigned as owner of the managed worktree (
[worktree-create] owner-thread-set); - the new task was renamed;
- the source task was archived with
source=thread_handoff; - the new task can be read and resumed.
However, Codex persists contradictory working-directory state for the new task:
session JSONL session_meta cwd: <managed-worktree>
thread/read cwd: <managed-worktree>
state_5.sqlite threads.cwd: <primary-checkout>
thread/list cwd: <primary-checkout>
The SQLite row has the new worktree branch but the old primary-checkout CWD. This looks like a partial handoff/reconciliation failure: the canonical session and managed-worktree ownership are updated, while the task index retains the source CWD. The UI then reports workspace-status-unavailable even though the directory and Git metadata are available.
This occurred with a managed worktree that had previously been used by earlier archived tasks. Historical records also contain both the symlinked $HOME/.codex/... spelling and its resolved external-volume spelling for the same physical worktree. That path normalization and/or worktree reuse may be relevant.
No raw logs are attached because they contain private repository names, local usernames, absolute paths, task IDs, branch names, and task previews.
What steps can reproduce the bug?
- On macOS, use a Git project in the Codex App primary checkout.
- Optionally configure
$HOME/.codexas a symlink to an external volume. - Use a Codex-managed worktree that has previously been associated with older tasks, then return the active task to the primary checkout.
- From the primary-checkout task, choose Hand off to a new worktree and enter a new branch name.
- Wait for Codex to fork the task, attach the managed worktree, and archive the source task.
- Open the newly created task.
- Observe the persistent
Couldn't check worktree statusbanner. - Compare the task's
session_meta.cwd/thread/readresult with thethreads.cwdrow instate_5.sqlite/thread/listresult.
What is the expected behavior?
Handoff should update the new task's worktree ownership, canonical session metadata, SQLite/indexed CWD, task-list CWD, sandbox roots, and UI state atomically—or reconcile them immediately after the handoff completes.
If the worktree exists and Git can inspect it, the composer should remain usable. Retry should repair or refresh stale metadata rather than repeatedly returning workspace-status-unavailable.
Additional information
This is a local handoff problem, not an SSH connectivity problem. Potentially related reports:
- #31210 reports the same banner for SSH remote sessions, but this reproduction is fully local.
- #25463 reports drift between session JSONL and local Desktop indexes, though its user-visible symptom is missing task history rather than a blocked worktree.
The data and Git branch remained recoverable; the impact is that the successfully created destination task cannot be used normally because the composer is disabled by the failed managed-worktree verification.
This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗