Skip to content

gpt-5.6-sol: "Script completed" is reported while the nested shell session is still running #34866

Description

@Rubicj

What version of Codex CLI is running?

codex-cli 0.145.0

What subscription do you have?

Pro

Which model were you using?

gpt-5.6-sol

What platform is your computer?

Linux 6.12.24-Unraid x86_64 unknown

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

n/a - Codex CLI runs inside a Docker container on Unraid

Codex doctor report

{
  "schemaVersion": 1,
  "generatedAt": "1784774745s since unix epoch",
  "overallStatus": "warning",
  "codexVersion": "0.145.0",
  "checks": {
    "app_server.status": {
      "id": "app_server.status",
      "category": "app-server",
      "status": "ok",
      "summary": "background server is not running",
      "details": {
        "control socket": "/home/node/.codex/app-server-control/app-server-control.sock",
        "daemon state dir": "/home/node/.codex/app-server-daemon",
        "mode": "ephemeral",
        "pid file": "/home/node/.codex/app-server-daemon/app-server.pid (missing)",
        "settings": "/home/node/.codex/app-server-daemon/settings.json (missing)",
        "status": "not running",
        "update-loop pid file": "/home/node/.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/node/.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/node/.codex",
        "config.toml": "/home/node/.codex/config.toml",
        "config.toml parse": "ok",
        "cwd": "/home/node",
        "enabled feature flags": "shell_tool, unified_exec, shell_snapshot, code_mode_host, terminal_resize_reflow, sqlite, hooks, enable_request_compression, multi_agent, apps, tool_search_always_defer_mcp_tools, tool_suggest, plugins, in_app_browser, browser_use, browser_use_full_cdp_access, browser_use_external, computer_use, remote_plugin, plugin_sharing, image_generation, resize_all_images, skill_mcp_dependency_install, skill_search, mentions_v2, steer, guardian_approval, goals, collaboration_modes, tool_call_mcp_elicitation, auth_elicitation, personality, fast_mode, tui_app_server, remote_compaction_v2, workspace_dependencies",
        "feature flag overrides": "none",
        "feature flags enabled": "36",
        "log dir": "/home/node/.codex/log",
        "mcp servers": "2",
        "model": "gpt-5.6-terra",
        "model provider": "openai",
        "sqlite home": "/home/node/.codex"
      },
      "remediation": null,
      "durationMs": 0
    },
    "git.environment": {
      "id": "git.environment",
      "category": "git",
      "status": "ok",
      "summary": "git version 2.39.5",
      "details": {
        "PATH git #1": "/usr/bin/git",
        "PATH git #2": "/bin/git",
        "PATH git entries": "2",
        "git build options": "git version 2.39.5; cpu: x86_64; no commit associated with this build; sizeof-long: 8; sizeof-size_t: 8; shell-path: /bin/sh",
        "git exec path": "/usr/lib/git-core",
        "git version": "git version 2.39.5",
        "repo detected": "false",
        "selected git": "/usr/bin/git"
      },
      "remediation": null,
      "durationMs": 14
    },
    "installation": {
      "id": "installation",
      "category": "install",
      "status": "ok",
      "summary": "installation looks consistent",
      "details": {
        "PATH codex #1": "/usr/local/bin/codex",
        "PATH codex #2": "/usr/local/bin/codex",
        "PATH codex entries": "2",
        "current executable": "/usr/local/lib/node_modules/@openai/codex-linux-x64/vendor/x86_64-unknown-linux-musl/bin/codex",
        "install context": "npm (package /usr/local/lib/node_modules/@openai/codex-linux-x64/vendor/x86_64-unknown-linux-musl, bin /usr/local/lib/node_modules/@openai/codex-linux-x64/vendor/x86_64-unknown-linux-musl/bin, resources /usr/local/lib/node_modules/@openai/codex-linux-x64/vendor/x86_64-unknown-linux-musl/codex-resources, path /usr/local/lib/node_modules/@openai/codex-linux-x64/vendor/x86_64-unknown-linux-musl/codex-path)",
        "managed by bun": "false",
        "managed by npm": "true",
        "managed by pnpm": "false",
        "managed package root": "/usr/local/lib/node_modules/@openai/codex",
        "npm update target": "/usr/local/lib/node_modules/@openai/codex"
      },
      "remediation": null,
      "durationMs": 74
    },
    "mcp.config": {
      "id": "mcp.config",
      "category": "mcp",
      "status": "ok",
      "summary": "MCP configuration is locally consistent",
      "details": {
        "configured servers": "2",
        "disabled servers": "0",
        "streamable_http servers": "2"
      },
      "remediation": null,
      "durationMs": 3185
    },
    "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 404)",
        "reachability mode": "ChatGPT auth"
      },
      "remediation": null,
      "durationMs": 658
    },
    "network.websocket_reachability": {
      "id": "network.websocket_reachability",
      "category": "websocket",
      "status": "ok",
      "summary": "Responses WebSocket handshake succeeded",
      "details": {
        "DNS": "2 IPv4, 2 IPv6, first IPv4",
        "auth mode": "chatgpt",
        "connect timeout": "15000 ms",
        "endpoint": "wss://chatgpt.com/backend-api/<redacted>",
        "handshake result": "HTTP 101 Switching Protocols",
        "model provider": "openai",
        "models etag present": "true",
        "provider name": "OpenAI",
        "proxy env vars": "none",
        "reasoning header": "false",
        "server model present": "false",
        "supports websockets": "true",
        "wire API": "responses"
      },
      "remediation": null,
      "durationMs": 530
    },
    "runtime.provenance": {
      "id": "runtime.provenance",
      "category": "runtime",
      "status": "ok",
      "summary": "running npm on linux-x86_64",
      "details": {
        "commit": "unknown",
        "current executable": "/usr/local/lib/node_modules/@openai/codex-linux-x64/vendor/x86_64-unknown-linux-musl/bin/codex",
        "install method": "npm (package /usr/local/lib/node_modules/@openai/codex-linux-x64/vendor/x86_64-unknown-linux-musl, bin /usr/local/lib/node_modules/@openai/codex-linux-x64/vendor/x86_64-unknown-linux-musl/bin, resources /usr/local/lib/node_modules/@openai/codex-linux-x64/vendor/x86_64-unknown-linux-musl/codex-resources, path /usr/local/lib/node_modules/@openai/codex-linux-x64/vendor/x86_64-unknown-linux-musl/codex-path)",
        "platform": "linux-x86_64",
        "version": "0.145.0"
      },
      "remediation": null,
      "durationMs": 0
    },
    "runtime.search": {
      "id": "runtime.search",
      "category": "search",
      "status": "ok",
      "summary": "search is OK (bundled)",
      "details": {
        "search command": "/usr/local/lib/node_modules/@openai/codex-linux-x64/vendor/x86_64-unknown-linux-musl/codex-path/rg",
        "search command readiness": "file exists",
        "search provider": "bundled"
      },
      "remediation": null,
      "durationMs": 0
    },
    "sandbox.helpers": {
      "id": "sandbox.helpers",
      "category": "sandbox",
      "status": "ok",
      "summary": "sandbox configuration is readable",
      "details": {
        "approval policy": "Never",
        "codex-linux-sandbox helper": "/home/node/.codex/tmp/arg0/codex-arg0NojShT/codex-linux-sandbox",
        "execve wrapper helper": "/home/node/.codex/tmp/arg0/codex-arg0NojShT/codex-execve-wrapper",
        "filesystem sandbox": "unrestricted",
        "network sandbox": "enabled"
      },
      "remediation": null,
      "durationMs": 0
    },
    "state.paths": {
      "id": "state.paths",
      "category": "state",
      "status": "ok",
      "summary": "state paths and databases are inspectable",
      "details": {
        "CODEX_HOME": "/home/node/.codex (dir)",
        "active rollout files": "1253 files, 826974886 total bytes, 659995 average bytes",
        "archived rollout files": "0 files, 0 total bytes, 0 average bytes",
        "goals DB": "/home/node/.codex/goals_1.sqlite (file)",
        "goals DB integrity": "ok",
        "log DB": "/home/node/.codex/logs_2.sqlite (file)",
        "log DB integrity": "ok",
        "log dir": "/home/node/.codex/log (dir)",
        "memories DB": "/home/node/.codex/memories_1.sqlite (file)",
        "memories DB integrity": "ok",
        "sqlite home": "/home/node/.codex (dir)",
        "state DB": "/home/node/.codex/state_5.sqlite (file)",
        "state DB integrity": "ok",
        "thread history DB": "/home/node/.codex/thread_history_1.sqlite (missing)",
        "thread history DB integrity": "skipped (missing)"
      },
      "remediation": null,
      "durationMs": 11907
    },
    "state.rollout_db_parity": {
      "id": "state.rollout_db_parity",
      "category": "threads",
      "status": "warning",
      "summary": "rollout files and state DB thread inventory differ",
      "details": {
        "default model provider": "openai",
        "rollout DB active files": "1253",
        "rollout DB active rows": "1231",
        "rollout DB archive mismatches": "0",
        "rollout DB archived files": "0",
        "rollout DB archived rows": "0",
        "rollout DB duplicate DB paths": "0",
        "rollout DB duplicate rollout thread ids": "0",
        "rollout DB malformed file names": "0",
        "rollout DB missing active rows": "23",
        "rollout DB missing active sample": [
          "/home/node/.codex/sessions/2026/07/06/rollout-2026-07-06T09-11-07-019f3832-97a9-7711-a261-b2ca7452ce9f.jsonl",
          "/home/node/.codex/sessions/2026/07/06/rollout-2026-07-06T12-09-02-019f38d5-7b28-71c2-8375-d9575962d949.jsonl",
          "/home/node/.codex/sessions/2026/07/06/rollout-2026-07-06T13-11-04-019f390e-456e-78d2-bcf1-3a8b90a4cb37.jsonl",
          "/home/node/.codex/sessions/2026/07/06/rollout-2026-07-06T14-01-32-019f393c-7b3e-7350-8f94-504093a23807.jsonl",
          "/home/node/.codex/sessions/2026/07/06/rollout-2026-07-06T14-07-57-019f3942-5800-7441-b220-9ed6565a1160.jsonl"
        ],
        "rollout DB missing archived rows": "0",
        "rollout DB model providers": "openai=1231",
        "rollout DB rows": "1231",
        "rollout DB scan cap reached": "false",
        "rollout DB scan errors": "0",
        "rollout DB sources": "cli=421, vscode=360, exec=316, subagent:thread_spawn=134",
        "rollout DB stale row sample": "/home/node/.codex/sessions/2026/07/16/rollout-2026-07-16T10-55-35-019f6c11-d30b-7253-b714-918f21f81fb3.jsonl",
        "rollout DB stale rows": "1"
      },
      "issues": [
        {
          "severity": "warning",
          "cause": "rollout files are missing from the state DB",
          "measured": "23 active, 0 archived",
          "expected": "every rollout file has a matching threads row",
          "remedy": null,
          "fields": []
        },
        {
          "severity": "warning",
          "cause": "state DB rows point at missing or unusable rollout files",
          "measured": "1 stale rows",
          "expected": "every state DB rollout path is a file on disk",
          "remedy": null,
          "fields": []
        }
      ],
      "remediation": null,
      "durationMs": 269
    },
    "system.environment": {
      "id": "system.environment",
      "category": "system",
      "status": "ok",
      "summary": "OS language unavailable",
      "details": {
        "EDITOR": "not set",
        "VISUAL": "not set",
        "os": "Debian 12.0.0 [64-bit]",
        "os language": "unavailable",
        "os type": "Debian",
        "os version": "12.0.0"
      },
      "remediation": null,
      "durationMs": 0
    },
    "terminal.env": {
      "id": "terminal.env",
      "category": "terminal",
      "status": "ok",
      "summary": "terminal metadata was detected",
      "details": {
        "TERM": "xterm-256color",
        "color output": "enabled",
        "stderr is terminal": "true",
        "stdin is terminal": "true",
        "stdout is terminal": "true",
        "terminal": "unknown",
        "terminal size": "209x51"
      },
      "remediation": null,
      "durationMs": 0
    },
    "terminal.title": {
      "id": "terminal.title",
      "category": "title",
      "status": "ok",
      "summary": "terminal title default",
      "details": {
        "terminal title activity": "true",
        "terminal title items": "activity, project-name",
        "terminal title project source": "cwd",
        "terminal title project value": "node",
        "terminal title source": "default"
      },
      "remediation": null,
      "durationMs": 0
    },
    "updates.status": {
      "id": "updates.status",
      "category": "updates",
      "status": "ok",
      "summary": "update configuration is locally consistent",
      "details": {
        "cached latest version": "0.145.0",
        "check for update on startup": "true",
        "dismissed version": "0.145.0",
        "last checked at": "2026-07-23T00:33:57.797494430Z",
        "latest version": "0.145.0",
        "latest version status": "current version is not older",
        "npm update target": "/usr/local/lib/node_modules/@openai/codex",
        "update action": "npm install -g @openai/codex",
        "version cache": "/home/node/.codex/version.json"
      },
      "remediation": null,
      "durationMs": 400
    }
  }
}

What issue are you seeing?

On Codex CLI 0.145.0 using gpt-5.6-sol, a single long-running foreground shell command can expose two independently resumable handles:

  • an outer JavaScript execution cell_id, resumed with wait;
  • an inner shell/PTY session_id, resumed with write_stdin.

The outer JavaScript cell can finish and display Script completed while the nested shell process is still running. The same completed outer result can contain a live SESSION_ID, so the transcript presents completion and non-completion simultaneously.

A representative sequence is:

Script running with cell ID <CELL_ID>

After one or more calls to wait(cell_id=<CELL_ID>):

Script completed
...
SESSION_ID=<SESSION_ID>

At that point, the requested shell command has not necessarily exited. Codex must switch to write_stdin(session_id=<SESSION_ID>, chars="") to retrieve the remaining output and final exit status. When that write_stdin call is itself wrapped in another JavaScript execution, it can produce another outer cell_id.

This causes several problems:

  • Script completed can be mistaken for completion of the requested command rather than only completion of the JavaScript wrapper.
  • One logical foreground command requires switching between two continuation APIs.
  • Repeated empty polling consumes additional model/tool turns.
  • The final output and exit status can be lost when generated JavaScript forwards only r.output and omits r.session_id or r.exit_code.
  • Codex can rerun a command after interpreting wrapper completion as process completion.

The command being run is an ordinary synchronous foreground process. It does not background itself or create either continuation identifier.

What steps can reproduce the bug?

Uploaded thread: 019f8ce9-8102-7270-9497-e4d3f5123342

Alternatively:

  1. Start a new Codex CLI thread using gpt-5.6-sol.

  2. Instruct Codex to invoke its code-mode exec tool with exactly this raw
    JavaScript, without replacing it with a direct shell invocation:

    // @exec: {"yield_time_ms": 2000, "max_output_tokens": 2000}
    const r = await tools.exec_command({
      cmd: "bash -lc 'echo START; sleep 30; echo FINISHED'",
      yield_time_ms: 8000,
      max_output_tokens: 2000
    });
    text(`OUTPUT=${r.output ?? ""}`);
    text(`SESSION_ID=${r.session_id ?? "null"}`);
    text(`EXIT_CODE=${r.exit_code ?? "null"}`);
  3. The timing is deliberate:

    outer exec yield:          2 seconds
    inner exec_command yield:  8 seconds
    shell command duration:   30 seconds
    

    Therefore the outer JavaScript must yield before the nested shell tool,
    and the nested shell tool must yield before the shell process exits.

  4. Inspect the raw rollout JSONL rather than only the rendered TUI
    transcript.

  5. Observe the outer call first returning:

    Script running with cell ID <CELL_ID>
    
  6. Resume it using wait(cell_id=<CELL_ID>).

  7. Observe the resolving outer result returning approximately:

    Script completed
    OUTPUT=START
    SESSION_ID=<SESSION_ID>
    EXIT_CODE=null
    

    FINISHED has not been emitted and no exit code exists, so the requested
    shell command remains active even though the outer result is labeled
    Script completed.

  8. Continue the returned shell session using:

    const r = await tools.write_stdin({
      session_id: <SESSION_ID>,
      chars: "",
      yield_time_ms: 30000,
      max_output_tokens: 2000
    });
    text(`OUTPUT=${r.output ?? ""}`);
    text(`SESSION_ID=${r.session_id ?? "null"}`);
    text(`EXIT_CODE=${r.exit_code ?? "null"}`);
  9. Observe that this later continuation returns FINISHED and exit code
    0. Confirm from the trace that the original shell command was invoked
    only once.

Actual result:

One logical foreground command exposes an outer cell_id resumed through
wait and then an inner session_id resumed through write_stdin. The
outer layer reports Script completed while the inner process is still
running.

Expected result:

The requested command should have one authoritative continuation lifecycle,
or the intermediate status should explicitly distinguish
wrapper completed from command still running.

What is the expected behavior?

One requested foreground command should have one authoritative logical lifecycle.

Preferably, Codex should expose one stable continuation identifier from command launch through process exit and internally supervise any nested shell session.

At minimum:

  • completed should mean that the requested shell command has terminated, not merely that its JavaScript wrapper returned.
  • While the shell process remains active, the result should explicitly say that the wrapper completed but the command is still running.
  • The response should identify one authoritative next operation instead of requiring the model to infer whether to use wait(cell_id) or write_stdin(session_id).
  • Incremental output, final output, and the terminal exit code should remain associated with the same logical operation.
  • Polling a running shell session should not create another independently exposed continuation lifecycle.

For example, an intermediate state could be represented as:

{
  "wrapper_state": "completed",
  "process_state": "running",
  "session_id": 12345,
  "next_operation": "write_stdin"
}

The user-facing status should then say Wrapper completed; command still running, not simply Script completed.

Additional information

I did not explicitly enable code_mode or code_mode_only in my Codex configuration. The behavior occurs with the default tool surface selected for gpt-5.6-sol.

This report is not asserting that Sol's use of code mode is itself a bug. The reported bug is that one requested shell command exposes both the outer JavaScript continuation and the inner process continuation, while the outer wrapper can be described as completed before the requested command has exited.

Related but distinct: #13733 tracks the model-turn and token cost of repeated write_stdin polling. This issue concerns the additional outer cell_id lifecycle, contradictory completion semantics, handle switching, and possible loss of the inner continuation or terminal exit result.

Metadata

Metadata

Assignees

No one assigned

    Labels

    CLIIssues related to the Codex CLIbugSomething isn't workingtool-callsIssues related to tool calling

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions