Codex CLI worktree session is interrupted when another Codex session is active in the base worktree

Open 💬 7 comments Opened May 19, 2026 by marcelodiaz558

What version of Codex CLI is running?

v0.131.0

What subscription do you have?

Pro

Which model were you using?

gpt-5.5 xhigh

What platform is your computer?

Linux 6.14.0-37-generic x86_64 x86_64

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

GNOME Terminal 3.52.0 using VTE 0.76.0, bash, Linux Mint Cinnamon, no tmux/zellij

Codex doctor report

{
  "schemaVersion": 1,
  "generatedAt": "1779213543s since unix epoch",
  "overallStatus": "fail",
  "codexVersion": "0.131.0",
  "checks": {
    "app_server.status": {
      "id": "app_server.status",
      "category": "app-server",
      "status": "ok",
      "summary": "background server is not running",
      "details": {
        "control socket": "/home/marcelo/.codex/app-server-control/app-server-control.sock",
        "daemon state dir": "/home/marcelo/.codex/app-server-daemon",
        "mode": "ephemeral",
        "pid file": "/home/marcelo/.codex/app-server-daemon/app-server.pid (missing)",
        "settings": "/home/marcelo/.codex/app-server-daemon/settings.json (missing)",
        "status": "not running",
        "update-loop pid file": "/home/marcelo/.codex/app-server-daemon/app-server-updater.pid (missing)"
      },
      "remediation": null,
      "durationMs": 0
    },
    "auth.credentials": {
      "id": "auth.credentials",
      "category": "auth",
      "status": "ok",
      "summary": "auth is configured",
      "details": {
        "auth file": "/home/marcelo/.codex/auth.json",
        "auth storage mode": "File",
        "stored API key": "false",
        "stored ChatGPT tokens": "true",
        "stored agent identity": "false",
        "stored auth mode": "chatgpt"
      },
      "remediation": null,
      "durationMs": 0
    },
    "config.load": {
      "id": "config.load",
      "category": "config",
      "status": "ok",
      "summary": "config loaded",
      "details": {
        "CODEX_HOME": "/home/marcelo/.codex",
        "config.toml": "/home/marcelo/.codex/config.toml",
        "config.toml parse": "ok",
        "cwd": "/home/marcelo/projects/codex",
        "enabled feature flags": "shell_tool, unified_exec, shell_snapshot, terminal_resize_reflow, sqlite, hooks, enable_request_compression, multi_agent, apps, tool_search, tool_suggest, plugins, plugin_hooks, in_app_browser, browser_use, browser_use_external, computer_use, plugin_sharing, image_generation, skill_mcp_dependency_install, steer, guardian_approval, collaboration_modes, tool_call_mcp_elicitation, personality, fast_mode, tui_app_server, workspace_dependencies",
        "feature flag overrides": "none",
        "feature flags enabled": "28",
        "log dir": "/home/marcelo/.codex/log",
        "mcp servers": "1",
        "model": "gpt-5.5",
        "model provider": "openai_high_retry",
        "sqlite home": "/home/marcelo/.codex"
      },
      "remediation": null,
      "durationMs": 0
    },
    "installation": {
      "id": "installation",
      "category": "install",
      "status": "ok",
      "summary": "installation looks consistent",
      "details": {
        "PATH codex #1": "/home/marcelo/.nvm/versions/node/v20.19.0/bin/codex",
        "current executable": "/home/marcelo/.nvm/versions/node/v20.19.0/lib/node_modules/@openai/codex/node_modules/@openai/codex-linux-x64/vendor/x86_64-unknown-linux-musl/codex/codex",
        "install context": "npm",
        "managed by bun": "false",
        "managed by npm": "true",
        "managed package root": "/home/marcelo/.nvm/versions/node/v20.19.0/lib/node_modules/@openai/codex",
        "npm update target": "/home/marcelo/.nvm/versions/node/v20.19.0/lib/node_modules/@openai/codex"
      },
      "remediation": null,
      "durationMs": 81
    },
    "mcp.config": {
      "id": "mcp.config",
      "category": "mcp",
      "status": "ok",
      "summary": "MCP configuration is locally consistent",
      "details": {
        "configured servers": "1",
        "disabled servers": "0",
        "stdio servers": "1"
      },
      "remediation": null,
      "durationMs": 0
    },
    "network.env": {
      "id": "network.env",
      "category": "network",
      "status": "ok",
      "summary": "network-related environment looks readable",
      "details": {
        "proxy env vars": "none"
      },
      "remediation": null,
      "durationMs": 0
    },
    "network.provider_reachability": {
      "id": "network.provider_reachability",
      "category": "reachability",
      "status": "ok",
      "summary": "active provider endpoints are reachable over HTTP",
      "details": {
        "ChatGPT base URL": "https://chatgpt.com/backend-api/ reachable (HTTP 403)",
        "reachability mode": "ChatGPT auth"
      },
      "remediation": null,
      "durationMs": 138
    },
    "network.websocket_reachability": {
      "id": "network.websocket_reachability",
      "category": "websocket",
      "status": "ok",
      "summary": "Responses WebSocket is not enabled for the active provider",
      "details": {
        "model provider": "openai_high_retry",
        "provider name": "OpenAI (high retry)",
        "proxy env vars": "none",
        "supports websockets": "false",
        "wire API": "responses"
      },
      "remediation": null,
      "durationMs": 0
    },
    "runtime.provenance": {
      "id": "runtime.provenance",
      "category": "runtime",
      "status": "ok",
      "summary": "running npm on linux-x86_64",
      "details": {
        "commit": "unknown",
        "current executable": "/home/marcelo/.nvm/versions/node/v20.19.0/lib/node_modules/@openai/codex/node_modules/@openai/codex-linux-x64/vendor/x86_64-unknown-linux-musl/codex/codex",
        "install method": "npm",
        "platform": "linux-x86_64",
        "version": "0.131.0"
      },
      "remediation": null,
      "durationMs": 0
    },
    "runtime.search": {
      "id": "runtime.search",
      "category": "search",
      "status": "ok",
      "summary": "search is OK (system)",
      "details": {
        "search command": "rg",
        "search command readiness": "ripgrep 15.1.0 (rev af60c2de9d)",
        "search provider": "system"
      },
      "remediation": null,
      "durationMs": 2
    },
    "sandbox.helpers": {
      "id": "sandbox.helpers",
      "category": "sandbox",
      "status": "ok",
      "summary": "sandbox configuration is readable",
      "details": {
        "approval policy": "OnRequest",
        "codex-linux-sandbox helper": "/home/marcelo/.codex/tmp/arg0/codex-arg0mZzoVv/codex-linux-sandbox",
        "execve wrapper helper": "/home/marcelo/.codex/tmp/arg0/codex-arg0mZzoVv/codex-execve-wrapper",
        "filesystem sandbox": "restricted",
        "network sandbox": "restricted"
      },
      "remediation": null,
      "durationMs": 0
    },
    "state.paths": {
      "id": "state.paths",
      "category": "state",
      "status": "fail",
      "summary": "state database integrity check failed",
      "details": {
        "CODEX_HOME": "/home/marcelo/.codex (dir)",
        "active rollout files": "2487 files, 1000606921 total bytes, 402334 average bytes",
        "archived rollout files": "0 files, 0 total bytes, 0 average bytes",
        "log DB": "/home/marcelo/.codex/logs_2.sqlite (file)",
        "log DB integrity": "*** in database main ***\nTree 5 page 68485 cell 18: Rowid 5163305 out of order\nTree 5 page 68484 cell 18: Rowid 5163048 out of order\nTree 5 page 68482 cell 18: Rowid 5165174 out of order\nTree 5 page 68481 cell 18: Rowid 5164300 out of order\nTree 5 page 68478 cell 18: Rowid 5165117 out of order\nTree 5 page 68476 cell 10: Rowid 5163713 out of order\nTree 5 page 68475 cell 11: Rowid 5163768 out of order\nTree 5 page 68472 cell 18: Rowid 5165402 out of order\nTree 5 page 68469 cell 18: Rowid 5163120 out of order\nTree 5 page 68468 cell 18: Rowid 5165307 out of order\nTree 5 page 68466 cell 7: Rowid 5163194 out of order\nTree 5 page 68463 right child: Bad ptr map entry key=68472 expected=(5,68463) got=(5,32174)\nTree 5 page 68463 right child: 2nd reference to page 68472\nTree 5 page 68463 right child: Rowid 5165383 out of order\nTree 5 page 68463 right child: Bad ptr map entry key=68419 expected=(5,68463) got=(5,32174)\nTree 5 page 68463 right child: Bad ptr map entry key=68395 expected=(5,68463) got=(5,2210)\nTree 5 page 68463 right child: Bad ptr map entry key=68364 expected=(5,68463) got=(5,31237)\nTree 5 page 68463 right child: Bad ptr map entry key=68414 expected=(5,68463) got=(5,32174)\nTree 5 page 68463 right child: Bad ptr map entry key=68468 expected=(5,68463) got=(5,32174)\nTree 5 page 68463 right child: 2nd reference to page 68468\nTree 5 page 68463 right child: Bad ptr map entry key=28065 expected=(5,68463) got=(5,31994)\nTree 5 page 68463 right child: Bad ptr map entry key=68452 expected=(5,68463) got=(5,32174)\nTree 5 page 68463 right child: Bad ptr map entry key=68425 expected=(5,68463) got=(5,32174)\nTree 5 page 68463 right child: Bad ptr map entry key=68363 expected=(5,68463) got=(5,32174)\nTree 5 page 68463 right child: Bad ptr map entry key=67948 expected=(5,68463) got=(5,32174)\nTree 5 page 68463 right child: Bad ptr map entry key=68456 expected=(5,68463) got=(3,68458)\nTree 5 page 68463 right child: Bad ptr map entry key=68482 expected=(5,68463) got=(5,32174)\nTree 5 page 68463 right child: 2nd reference to page 68482\nTree 5 page 68463 right child: Bad ptr map entry key=30099 expected=(5,68463) got=(5,47192)\nTree 5 page 68463 right child: Bad ptr map entry key=68474 expected=(5,68463) got=(5,47192)\nTree 5 page 68463 right child: Bad ptr map entry key=68478 expected=(5,68463) got=(5,32174)\nTree 5 page 68463 right child: 2nd reference to page 68478\nTree 5 page 68463 right child: Bad ptr map entry key=68026 expected=(5,68463) got=(5,32174)\nTree 5 page 68463 right child: Bad ptr map entry key=68094 expected=(5,68463) got=(5,5729)\nTree 5 page 68463 right child: Bad ptr map entry key=68454 expected=(5,68463) got=(5,32174)\nTree 5 page 68463 right child: Bad ptr map entry key=68420 expected=(5,68463) got=(5,32174)\nTree 5 page 68463 right child: Bad ptr map entry key=68451 expected=(5,68463) got=(5,32174)\nTree 5 page 68463 right child: Bad ptr map entry key=68490 expected=(5,68463) got=(5,62984)\nTree 5 page 68463 right child: Bad ptr map entry key=68316 expected=(5,68463) got=(5,32174)\nTree 5 page 68463 right child: Bad ptr map entry key=67749 expected=(5,68463) got=(5,32174)\nTree 5 page 68463 right child: Bad ptr map entry key=67736 expected=(5,68463) got=(5,32174)\nTree 5 page 68463 right child: Bad ptr map entry key=67956 expected=(5,68463) got=(5,47192)\nTree 5 page 68463 right child: Bad ptr map entry key=68461 expected=(5,68463) got=(2,0)\nTree 5 page 68463 right child: Bad ptr map entry key=68428 expected=(5,68463) got=(5,32174)\nTree 5 page 68463 right child: Bad ptr map entry key=68383 expected=(5,68463) got=(5,32174)\nTree 5 page 68463 right child: Bad ptr map entry key=67930 expected=(5,68463) got=(5,32174)\nTree 5 page 68463 right child: Bad ptr map entry key=68460 expected=(5,68463) got=(5,32174)\nTree 5 page 68463 right child: Bad ptr map entry key=68408 expected=(5,68463) got=(5,32174)\nTree 5 page 68463 right child: Bad ptr map entry key=68011 expected=(5,68463) got=(5,32174)\nTree 5 page 68463 right child: Bad ptr map entry key=68453 expected=(5,68463) got=(5,32174)\nTree 5 page 68463 right child: Bad ptr map entry key=67966 expected=(5,68463) got=(5,47192)\nTree 5 page 68463 right child: Bad ptr map entry key=67684 expected=(5,68463) got=(5,10401)\nTree 5 page 68463 right child: Bad ptr map entry key=67939 expected=(5,68463) got=(5,5729)\nTree 5 page 68463 right child: Bad ptr map entry key=68412 expected=(5,68463) got=(5,32174)\nTree 5 page 68463 right child: Bad ptr map entry key=68376 expected=(5,68463) got=(5,32174)\nTree 5 page 68463 right child: Bad ptr map entry key=68405 expected=(5,68463) got=(5,5729)\nTree 5 page 68463 right child: Bad ptr map entry key=68005 expected=(5,68463) got=(5,31994)\nTree 5 page 68463 right child: Bad ptr map entry key=68434 expected=(5,68463) got=(5,32174)\nTree 5 page 68463 right child: Bad ptr map entry key=68110 expected=(5,68463) got=(5,5729)\nTree 5 page 68463 right child: Bad ptr map entry key=68464 expected=(5,68463) got=(5,47192)\nTree 5 page 68463 right child: Bad ptr map entry key=68411 expected=(5,68463) got=(5,5729)\nTree 5 page 68463 right child: Bad ptr map entry key=68429 expected=(5,68463) got=(5,32174)\nTree 5 page 68463 right child: Bad ptr map entry key=68427 expected=(5,68463) got=(5,32174)\nTree 5 page 68463 right child: Bad ptr map entry key=68378 expected=(5,68463) got=(5,5729)\nTree 5 page 68463 right child: Bad ptr map entry key=68379 expected=(5,68463) got=(5,32174)\nTree 5 page 68463 right child: Bad ptr map entry key=68483 expected=(5,68463) got=(5,62984)\nTree 5 page 68463 right child: Bad ptr map entry key=68455 expected=(5,68463) got=(5,32174)\nTree 5 page 68463 right child: Bad ptr map entry key=68360 expected=(5,68463) got=(5,32174)\nTree 5 page 68463 right child: Bad ptr map entry key=68385 expected=(5,68463) got=(5,32174)\nTree 5 page 68463 right child: Bad ptr map entry key=68296 expected=(5,68463) got=(5,32174)\nTree 5 page 68463 right child: Bad ptr map entry key=68356 expected=(5,68463) got=(5,5729)\nTree 5 page 68463 right child: Bad ptr map entry key=68020 expected=(5,68463) got=(5,32174)\nTree 5 page 68463 right child: Bad ptr map entry key=67685 expected=(5,68463) got=(5,31994)\nTree 5 page 68463 right child: Bad ptr map entry key=68430 expected=(5,68463) got=(5,32174)\nTree 5 page 68463 right child: Bad ptr map entry key=68481 expected=(5,68463) got=(5,32174)\nTree 5 page 68463 right child: 2nd reference to page 68481\nTree 5 page 68463 right child: Bad ptr map entry key=68406 expected=(5,68463) got=(5,32174)\nTree 5 page 68463 right child: Bad ptr map entry key=68403 expected=(5,68463) got=(5,32174)\nTree 5 page 68463 right child: Bad ptr map entry key=67945 expected=(5,68463) got=(5,50770)\nTree 5 page 68463 right child: Bad ptr map entry key=68380 expected=(5,68463) got=(5,5729)\nTree 5 page 68463 right child: Bad ptr map entry key=68367 expected=(5,68463) got=(5,32174)\nTree 5 page 68463 right child: Bad ptr map entry key=68369 expected=(5,68463) got=(5,32174)\nTree 5 page 68463 right child: Bad ptr map entry key=68410 expected=(5,68463) got=(5,32174)\nTree 5 page 68463 right child: Bad ptr map entry key=68368 expected=(5,68463) got=(5,32174)\nTree 5 page 68463 right child: Bad ptr map entry key=64763 expected=(5,68463) got=(5,32174)\nTree 5 page 68463 right child: Bad ptr map entry key=68372 expected=(5,68463) got=(5,2210)\nTree 5 page 68463 right child: Bad ptr map entry key=68097 expected=(5,68463) got=(5,32174)\nTree 5 page 68463 right child: Bad ptr map entry key=68424 expected=(5,68463) got=(5,32174)\nTree 5 page 68463 right child: Bad ptr map entry key=68373 expected=(5,68463) got=(5,32174)\nTree 5 page 68463 right child: Bad ptr map entry key=68436 expected=(5,68463) got=(5,2210)\nTree 5 page 68463 right child: Bad ptr map entry key=68358 expected=(5,68463) got=(5,32174)\nTree 5 page 68463 right child: Bad ptr map entry key=68133 expected=(5,68463) got=(5,32174)\nTree 5 page 68463 right child: Bad ptr map entry key=68413 expected=(5,68463) got=(5,32174)\nTree 5 page 68463 right child: Bad ptr map entry key=68063 expected=(5,68463) got=(5,31237)\nTree 5 page 68463 right child: Bad ptr map entry key=68433 expected=(5,68463) got=(5,32174)\nTree 5 page 68463 right child: Bad ptr map entry key=68435 expected=(5,68463) got=(5,32174)\nTree 5 page 68463 right child: Bad ptr map entry key=68423 expected=(5,68463) got=(5,32174)\nTree 5 page 68463 right child: Bad ptr map entry key=68448 expected=(5,68463) got=(5,50770)\nTree 5 page 68463 right child: Bad ptr map entry key=68407 expected=(5,68463) got=(5,32174)\nTree 5 page 68463 right child: Bad ptr map entry key=68365 expected=(5,68463) got=(5,32174)",
        "log dir": "/home/marcelo/.codex/log (dir)",
        "sqlite home": "/home/marcelo/.codex (dir)",
        "state DB": "/home/marcelo/.codex/state_5.sqlite (file)",
        "state DB integrity": "ok"
      },
      "remediation": "Back up CODEX_HOME, then remove or repair the affected SQLite database.",
      "durationMs": 10822
    },
    "terminal.env": {
      "id": "terminal.env",
      "category": "terminal",
      "status": "ok",
      "summary": "terminal metadata was detected",
      "details": {
        "COLORTERM": "truecolor",
        "DISPLAY": "present",
        "color output": "enabled",
        "effective locale": "en_US.UTF-8",
        "stderr is terminal": "true",
        "stdin is terminal": "true",
        "stdout is terminal": "true",
        "terminal": "GNOME Terminal",
        "terminal size": "285x53"
      },
      "remediation": null,
      "durationMs": 0
    },
    "updates.status": {
      "id": "updates.status",
      "category": "updates",
      "status": "ok",
      "summary": "update configuration is locally consistent",
      "details": {
        "cached latest version": "0.131.0",
        "check for update on startup": "true",
        "dismissed version": "0.116.0",
        "last checked at": "2026-05-19T15:26:53.505030797Z",
        "latest version": "0.131.0",
        "latest version status": "current version is not older",
        "npm update target": "/home/marcelo/.nvm/versions/node/v20.19.0/lib/node_modules/@openai/codex",
        "update action": "npm install -g @openai/codex",
        "version cache": "/home/marcelo/.codex/version.json"
      },
      "remediation": null,
      "durationMs": 461
    }
  }
}

What issue are you seeing?

When I create a fresh Git worktree, Codex initially starts correctly inside the new worktree. However, if another Codex TUI session is already running in the original/base worktree and that session is processing a message, the Codex session in the new worktree gets interrupted.

The TUI shows:

Error: turn/start failed in TUI

After that interruption, Codex can no longer be started from the new worktree. Running codex again fails with:

Error loading config.toml: Failed to read project hooks config file /home/user/projects/example/base-worktree/.codex/config.toml: Not a directory (os error 20)

The path in the error points back to the original/base worktree, even though the command is being run from the new worktree.

What steps can reproduce the bug?

  1. Start with a repository at a sample path like:
/home/user/projects/example/base-worktree
  1. Start Codex in the base worktree.
  1. In another terminal, create a new Git worktree:
git worktree add -b test/worktree-branch ../worktree-branch
cd ../worktree-branch
  1. Start Codex in the new worktree:
codex
  1. Send a message while still using codex in the base worktree, just working normally on both terminals
  1. The Codex session in the new worktree can suddenly be interrupted with:
Error: turn/start failed in TUI
  1. Exit and try to start Codex again in the new worktree:
codex
  1. Codex fails to start with:
Error loading config.toml: Failed to read project hooks config file /home/user/projects/example/base-worktree/.codex/config.toml: Not a directory (os error 20)

What is the expected behavior?

A Codex session running in a Git worktree should be isolated from any Codex session running in the base worktree.

Starting or using Codex in the new worktree should not be interrupted because another Codex session is active in the base worktree, and subsequent codex launches from the new worktree should resolve configuration relative to the correct worktree.

Additional information

Creating another fresh worktree avoids the error, which suggests some local worktree/session state may be left in a bad state after the interruption.

View original on GitHub ↗

7 Comments

jshaofa-ui · 2 months ago

🔧 Proposed Fix: Key Sessions by Worktree Path, Not Repo Path

Root Cause

Codex's session registry likely keys sessions by repo path (not worktree path). When a new session starts in the base worktree, it collides with the existing worktree session — either overwriting the registry entry, conflicting on lock files, or triggering session cleanup logic.

Fix

1. Key sessions by worktree path:

function getSessionKey(cwd: string): string {
  const worktreePath = getGitWorktreePath(cwd);
  const repoRoot = getGitRepoRoot(cwd);
  if (worktreePath && worktreePath !== repoRoot) {
    return `worktree:${worktreePath}`;  // Worktree-specific key
  }
  return `repo:${repoRoot}`;  // Base worktree key
}

2. Separate lock files per worktree:

function getLockFilePath(cwd: string): string {
  const worktreePath = getGitWorktreePath(cwd);
  const repoRoot = getGitRepoRoot(cwd);
  if (worktreePath !== repoRoot) {
    return path.join(repoRoot, `.codex-worktree-${path.basename(worktreePath)}-lock`);
  }
  return path.join(repoRoot, '.codex-lock');
}

Why This Works

  • Each worktree gets its own session entry and lock file
  • Base worktree and feature worktrees can run in parallel without interference
  • ~30 lines of TypeScript, purely additive
  • Doesn't change non-worktree behavior

Competitive Edge

  • Zero competition (0 comments, no PRs)
  • Affects developers using git worktrees for parallel branch development
  • User has detailed codex doctor output and exact version info

---

<details>
<summary>📋 Full Technical Analysis</summary>

Solution: openai/codex #23515 — Worktree Session Interrupted by Base Worktree Session

Issue Summary

When a Codex CLI session is running in a git worktree, starting another Codex session in the base worktree (main repo) interrupts the worktree session. This prevents parallel work on different branches.

Root Cause Analysis

The Conflict

Git worktrees share the same .git directory (the main repo's .git). When two Codex sessions operate on the same repo simultaneously:

  1. Both sessions may try to read/write shared state files
  2. Git index locks may conflict
  3. Codex's session management may not distinguish worktree sessions from base sessions
  4. The base worktree session may trigger operations that invalidate the worktree session's state

Likely Mechanism

Codex likely uses a session registry or lock file keyed by repo path (not worktree path). When a new session starts in the base worktree:

  1. It registers itself in the session registry under the repo's path
  2. The existing worktree session is either:
  • Overwritten (same key collision)
  • Invalidated (lock file conflict)
  • Terminated (session cleanup logic)

Proposed Fix

Fix: Key sessions by worktree path, not repo path

// In session registry:
function getSessionKey(cwd: string): string {
  // Get the git worktree path for this directory
  const worktreePath = getGitWorktreePath(cwd);
  if (worktreePath && worktreePath !== getGitRepoRoot(cwd)) {
    // This is a worktree — use worktree-specific key
    return `worktree:${worktreePath}`;
  }
  // Base worktree or non-git directory
  return `repo:${getGitRepoRoot(cwd)}`;
}

// Session registration:
async function registerSession(cwd: string) {
  const key = getSessionKey(cwd);
  // Each worktree gets its own session entry
  await sessionRegistry.set(key, { pid: process.pid, cwd, startedAt: Date.now() });
}

Fix: Separate lock files per worktree

// Lock file path should include worktree identifier
function getLockFilePath(cwd: string): string {
  const worktreePath = getGitWorktreePath(cwd);
  const repoRoot = getGitRepoRoot(cwd);
  
  if (worktreePath !== repoRoot) {
    // Use worktree-specific lock
    const worktreeName = path.basename(worktreePath);
    return path.join(repoRoot, `.codex-worktree-${worktreeName}-lock`);
  }
  return path.join(repoRoot, '.codex-lock');
}

Estimated Impact

  • Affects developers who use git worktrees for parallel branch development
  • Prevents the natural workflow of having CLI in worktree + Desktop in base repo
  • Fix is ~30 lines of TypeScript (session key + lock path)
  • Zero risk: purely additive, doesn't change non-worktree behavior

Competitive Analysis

  • Zero competition: 0 comments, no PRs
  • Labels: TUI, CLI, session, config — core session management
  • User has: detailed codex doctor output, exact version info, platform details

</details>

marcelodiaz558 · 2 months ago

Update: I noticed that a Codex session doesn’t need to be running in the base worktree for the Error: turn/start failed in TUI error to occur. The issue can happen in any worktree, and it appears either when an AI turn ends or when you try to send a new message to an ongoing session. It doesn’t seem to interrupt running sessions until the turn ends, unless we try sending a new message in a session with context used while it’s waiting for input.

fcurti-ar · 1 month ago

+1 to this. I got this error several times now, codex ends up in a broken state, I cannot work using worktrees.

jclark · 1 month ago

I get this all the time. I was able to workaround iby doing rmdir .codex in the worktree. With the TUI, you can then resume, although annoyingly the last prompt gets erased. It's less painful in the vscode extension: just rmdir .codex and continue.

iqdoctor · 1 month ago

Additional data point for the same Error: turn/start failed in TUI symptom, observed on a newer CLI:

  • Codex CLI: codex-cli 0.138.0 (@openai/codex package 0.138.0)
  • Platform: Linux x86_64, inside tmux/attached terminal runtime
  • Repo/worktree context: session was running in a git worktree under /home/tools/oh-my-codex.omx-worktrees/...
  • Visible terminal output after the previous assistant final answer:
Posted PR comment:
https://github.com/Yeachan-Heo/oh-my-codex/pull/2774#issuecomment-4663939642

Error: turn/start failed in TUI
[omx] codex exited with code 1

What I could verify locally:

  • The prior turn completed successfully and persisted normally.
  • Thread id: 019eae25-5763-79f3-8810-d78e8f4af090
  • Last completed turn id: 019eae2a-ff76-75e2-8ac9-4bcd41295c7b
  • Session JSONL had task_complete at 2026-06-09T20:55:35.260Z.
  • The GitHub comment operation itself succeeded; the crash happened after that final answer, when the TUI tried to start/accept the next turn.
  • No subsequent user turn was persisted in that session JSONL after task_complete, which makes the failure look like it occurred before the next turn was recorded.
  • Querying Codex SQLite logs for 2026-06-09T20:55:00Z through 2026-06-09T21:04:00Z showed no ERROR rows. The only relevant warning I saw was:
Model personality requested but model_messages is missing, falling back to base instructions. model=gpt-5.5 personality=pragmatic

I also checked current main after git pull (9e3081be96) and the visible message appears to be the TUI wrapper around turn/start, not an OMX-specific error. Relevant code paths I found:

  • codex-rs/tui/src/app_server_session.rs wraps the request with turn/start failed in TUI.
  • codex-rs/app-server-client/src/lib.rs has more specific error categories (Transport, Server, Deserialize) that are not visible in the terminal output here.

I do not have a deterministic repro yet. This comment is intended as an additional data point that the same visible failure still occurs on 0.138.0, after a successfully completed turn, and not only while changing permissions. A useful improvement would be surfacing the underlying turn/start request/server error details in the TUI so users can distinguish transport failure vs server rejection vs decode failure.

codex doctor --json did not return promptly in this environment, so I am not attaching a doctor report yet.

iqdoctor · 1 month ago

Follow-up: codex doctor --json eventually returned after about 54 seconds. Redacted/notable summary from the same environment:

codexVersion: 0.138.0
overallStatus: warning
app_server.status: ok — background server is not running (ephemeral)
installation: ok — npm install looks consistent
network.provider_reachability: ok
network.websocket_reachability: ok — Responses WebSocket handshake succeeded
state.paths: ok — logs/state/memories/goals DB integrity ok
terminal.env: ok — Ghostty 1.3.1 inside tmux 3.4
updates.status: ok — latest version 0.139.0 available

Only warning:

state.rollout_db_parity: warning — rollout files and state DB thread inventory differ
rollout DB active files: 1147
rollout DB active rows: 1142
rollout DB missing active rows: 5
rollout DB duplicate rollout thread ids: 0
rollout DB stale rows: 0

This may or may not be related to the observed turn/start failed in TUI, but it is the only non-ok doctor check from the environment where the failure was observed.

mkurz · 12 days ago

+1 same here