Native resume_agent silently changes a subagent’s model
What version of Codex CLI is running?
codex-cli 0.146.0
What subscription do you have?
pro
Which model were you using?
Child spawned as gpt-5.6-luna; parent/default was gpt-5.6-sol. On native resume, the child silently resumed as gpt-5.6-sol.
What platform is your computer?
Linux x86_64
What terminal emulator and version are you using (if applicable)?
VScode over ssh
Codex doctor report
{
"schemaVersion": 1,
"generatedAt": "1785560984s since unix epoch",
"overallStatus": "warning",
"codexVersion": "0.146.0",
"checks": {
"app_server.status": {
"id": "app_server.status",
"category": "app-server",
"status": "ok",
"summary": "background server is not running",
"details": {
"control socket": "/root/.codex/app-server-control/app-server-control.sock",
"daemon state dir": "/root/.codex/app-server-daemon",
"mode": "ephemeral",
"pid file": "/root/.codex/app-server-daemon/app-server.pid (missing)",
"settings": "/root/.codex/app-server-daemon/settings.json (missing)",
"status": "not running",
"update-loop pid file": "/root/.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": "/root/.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": "/root/.codex",
"config.toml": "/root/.codex/config.toml",
"config.toml parse": "ok",
"cwd": "/root/hindsight-upstream-pr",
"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, in_app_updates, browser_use, browser_use_full_cdp_access, browser_use_external, computer_use, remote_plugin, plugin_sharing, image_generation, resize_all_images, item_ids, 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": "38",
"log dir": "/root/.codex/log",
"mcp servers": "1",
"model": "gpt-5.6-sol",
"model provider": "openai",
"sqlite home": "/root/.codex"
},
"remediation": null,
"durationMs": 0
},
"git.environment": {
"id": "git.environment",
"category": "git",
"status": "ok",
"summary": "git version 2.39.5",
"details": {
".git entry": "file -> /root/hindsight/.git/worktrees/hindsight-upstream-pr",
"PATH git #1": "/usr/bin/git",
"PATH git #2": "/bin/git",
"PATH git entries": "2",
"git branch": "fix/litellm-sdk-embedding-retry",
"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": "true",
"repo root": "/root/hindsight-upstream-pr",
"selected git": "/usr/bin/git"
},
"remediation": null,
"durationMs": 27
},
"installation": {
"id": "installation",
"category": "install",
"status": "ok",
"summary": "installation looks consistent",
"details": {
"PATH codex #1": "/root/.nvm/versions/node/v22.22.3/bin/codex",
"current executable": "/root/.nvm/versions/node/v22.22.3/lib/node_modules/@openai/codex/node_modules/@openai/codex-linux-x64/vendor/x86_64-unknown-linux-musl/bin/codex",
"install context": "npm (package /root/.nvm/versions/node/v22.22.3/lib/node_modules/@openai/codex/node_modules/@openai/codex-linux-x64/vendor/x86_64-unknown-linux-musl, bin /root/.nvm/versions/node/v22.22.3/lib/node_modules/@openai/codex/node_modules/@openai/codex-linux-x64/vendor/x86_64-unknown-linux-musl/bin, resources /root/.nvm/versions/node/v22.22.3/lib/node_modules/@openai/codex/node_modules/@openai/codex-linux-x64/vendor/x86_64-unknown-linux-musl/codex-resources, path /root/.nvm/versions/node/v22.22.3/lib/node_modules/@openai/codex/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": "/root/.nvm/versions/node/v22.22.3/lib/node_modules/@openai/codex",
"npm update target": "/root/.nvm/versions/node/v22.22.3/lib/node_modules/@openai/codex"
},
"remediation": null,
"durationMs": 90
},
"mcp.config": {
"id": "mcp.config",
"category": "mcp",
"status": "ok",
"summary": "MCP configuration is locally consistent",
"details": {
"configured servers": "1",
"disabled servers": "0",
"streamable_http servers": "1"
},
"remediation": null,
"durationMs": 61
},
"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": 225
},
"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": 678
},
"runtime.provenance": {
"id": "runtime.provenance",
"category": "runtime",
"status": "ok",
"summary": "running npm on linux-x86_64",
"details": {
"commit": "unknown",
"current executable": "/root/.nvm/versions/node/v22.22.3/lib/node_modules/@openai/codex/node_modules/@openai/codex-linux-x64/vendor/x86_64-unknown-linux-musl/bin/codex",
"install method": "npm (package /root/.nvm/versions/node/v22.22.3/lib/node_modules/@openai/codex/node_modules/@openai/codex-linux-x64/vendor/x86_64-unknown-linux-musl, bin /root/.nvm/versions/node/v22.22.3/lib/node_modules/@openai/codex/node_modules/@openai/codex-linux-x64/vendor/x86_64-unknown-linux-musl/bin, resources /root/.nvm/versions/node/v22.22.3/lib/node_modules/@openai/codex/node_modules/@openai/codex-linux-x64/vendor/x86_64-unknown-linux-musl/codex-resources, path /root/.nvm/versions/node/v22.22.3/lib/node_modules/@openai/codex/node_modules/@openai/codex-linux-x64/vendor/x86_64-unknown-linux-musl/codex-path)",
"platform": "linux-x86_64",
"version": "0.146.0"
},
"remediation": null,
"durationMs": 0
},
"runtime.search": {
"id": "runtime.search",
"category": "search",
"status": "ok",
"summary": "search is OK (bundled)",
"details": {
"search command": "/root/.nvm/versions/node/v22.22.3/lib/node_modules/@openai/codex/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": "OnRequest",
"codex-linux-sandbox helper": "/root/.codex/tmp/arg0/codex-arg0QOVDKn/codex-linux-sandbox",
"execve wrapper helper": "/root/.codex/tmp/arg0/codex-arg0QOVDKn/codex-execve-wrapper",
"filesystem sandbox": "restricted",
"network sandbox": "restricted"
},
"remediation": null,
"durationMs": 0
},
"state.paths": {
"id": "state.paths",
"category": "state",
"status": "ok",
"summary": "state paths and databases are inspectable",
"details": {
"CODEX_HOME": "/root/.codex (dir)",
"active rollout files": "155 files, 807701037 total bytes, 5210974 average bytes",
"archived rollout files": "0 files, 0 total bytes, 0 average bytes",
"goals DB": "/root/.codex/goals_1.sqlite (file)",
"goals DB integrity": "ok",
"log DB": "/root/.codex/logs_2.sqlite (file)",
"log DB integrity": "ok",
"log dir": "/root/.codex/log (missing)",
"memories DB": "/root/.codex/memories_1.sqlite (file)",
"memories DB integrity": "ok",
"sqlite home": "/root/.codex (dir)",
"state DB": "/root/.codex/state_5.sqlite (file)",
"state DB integrity": "ok",
"thread history DB": "/root/.codex/thread_history_1.sqlite (missing)",
"thread history DB integrity": "skipped (missing)"
},
"remediation": null,
"durationMs": 581
},
"state.rollout_db_parity": {
"id": "state.rollout_db_parity",
"category": "threads",
"status": "ok",
"summary": "rollout files and state DB thread inventory agree",
"details": {
"default model provider": "openai",
"rollout DB active files": "155",
"rollout DB active rows": "155",
"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": "0",
"rollout DB missing archived rows": "0",
"rollout DB model providers": "openai=155",
"rollout DB rows": "155",
"rollout DB scan cap reached": "false",
"rollout DB scan errors": "0",
"rollout DB sources": "subagent:thread_spawn=135, cli=11, vscode=5, exec=4",
"rollout DB stale rows": "0"
},
"remediation": null,
"durationMs": 133
},
"system.environment": {
"id": "system.environment",
"category": "system",
"status": "ok",
"summary": "OS language C",
"details": {
"EDITOR": "not set",
"LANG": "en_US.UTF-8",
"LC_ALL": "C.UTF-8",
"VISUAL": "not set",
"os": "Debian 12.0.0 (bookworm) [64-bit]",
"os language": "C",
"os type": "Debian",
"os version": "12.0.0"
},
"remediation": null,
"durationMs": 11
},
"terminal.env": {
"id": "terminal.env",
"category": "terminal",
"status": "warning",
"summary": "height 12 rows - content may scroll off (recommended >=24)",
"details": {
"COLORTERM": "truecolor",
"SSH_CLIENT": "present",
"SSH_CONNECTION": "present",
"TERM_PROGRAM": "vscode",
"VSCODE_IPC_HOOK_CLI": "present",
"color output": "enabled",
"effective locale": "C.UTF-8",
"stderr is terminal": "true",
"stdin is terminal": "true",
"stdout is terminal": "true",
"terminal": "VS Code",
"terminal size": "174x12",
"terminal version": "1.130.0"
},
"issues": [
{
"severity": "warning",
"cause": "height 12 rows - content may scroll off (recommended >=24)",
"measured": "174 x 12",
"expected": ">= 24 rows",
"remedy": "resize the window to at least 24 rows",
"fields": [
"terminal size"
]
}
],
"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": "git repo root",
"terminal title project value": "hindsight-upstream-pr",
"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.146.0",
"check for update on startup": "true",
"last checked at": "2026-07-30T10:29:14.675409397Z",
"latest version": "0.146.0",
"latest version status": "current version is not older",
"npm update target": "/root/.nvm/versions/node/v22.22.3/lib/node_modules/@openai/codex",
"update action": "npm install -g @openai/codex",
"version cache": "/root/.codex/version.json"
},
"remediation": null,
"durationMs": 547
}
}
}
What issue are you seeing?
A child explicitly spawned with gpt-5.6-luna was completed, closed, and
later resumed using the native resume_agent multi-agent tool. It
retained the same child identity but silently resumed as gpt-5.6-sol,
the parent/config default.
The native resume tool accepts only id. It provides no model or
reasoning-effort override and does not report that the effective model
changed.
This affects review provenance and model/cost-routing policy because one
child session identity can silently represent work performed by different
model classes.
The relevant implementation is in:
codex-rs/core/src/tools/handlers/multi_agents/resume_agent.rs
What steps can reproduce the bug?
- Set the parent/default model to
gpt-5.6-sol. - Enable native multi-agent support.
- Spawn a child explicitly pinned to
gpt-5.6-luna. - Let the child complete and close.
- Resume it using native
resume_agent({"id":"<child-thread-id>"}). - Observe that the same child identity resumes as
gpt-5.6-sol, rather
than its persisted gpt-5.6-luna model.
The native resume_agent schema accepts only id, so there is no way to
preserve or explicitly restore the intended model through this tool.
What is the expected behavior?
Native subagent resume should preserve the child thread's persisted model
and reasoning effort by default.
If explicit overrides are supported, resume_agent should accept model
and reasoning-effort fields. Any unavoidable substitution should report
the persisted, requested, and effective model before running the resumed
turn.
Additional information
Ordinary CLI resume exposes explicit model selection:
codex resume --model <MODEL>codex exec resume --model <MODEL>
Related issues:
- #32061: ordinary session resume should restore persisted model and
effort.
- #31814: subagent model fields hidden under some multi-agent
configurations.
This report is specifically about native multi-agent resume_agent
silently changing the child model while retaining the child identity.
1 Comment
I traced this to the rollout-resume config handoff rather than the native tool schema itself.
Both
resume_single_agent_from_rolloutand the unloaded multi-agent v2 path readStoredThread, but reopen the thread with a config derived from the current parent/session. They restore identity metadata while leavingmodel,model_provider, andmodel_reasoning_effortinherited from that caller config.A narrow fix is to overlay the stored model selection before role/source reconstruction:
Noneso a parent's explicit effort does not leak into the childI built and validated a reference implementation here: https://github.com/Epochex/codex/commit/9765a29
Validation on Windows:
just test -p codex-core agent::control— 60/60 passedgpt-5.4/Highwhile the caller config differscargo fmt --all -- --checkandgit diff --checkpassedI did not open a PR because the repository's current contribution policy limits external code PRs to invited contributors. The branch is available if the team wants to reuse it or invite a PR.