Bug: MCP tool-call meta serialization failure silently drops sandbox state
Nobody has claimed this yet.
Assessment
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Newbie friendliness
- 78/100
Research direction
Start with the conversion sites at codex-mcp/src/binding.rs:290 and codex-mcp/src/connection_manager.rs:629, then trace how MCP tool-call meta and content serialization failures reach downstream consumers. Reproduce a non-serializable result if possible; done means failures are observable at warn level and sandbox-related meta or tool output is not silently discarded without an explicit fallback.
Written by the indexing model from the issue text.
Description
What version of Codex CLI is running?
Reproduced with codex-cli 0.145.0. The same implementation is still present in main at e4fb5311d7468839def62eabda4b268f4a54cf11.
What platform is your computer?
Darwin 26.5.2 arm64 arm (macOS).
What issue are you seeing?
When an MCP tool call returns a meta field that cannot be serialized to JSON, the meta is silently set to None instead of propagating an error. This can cause the sandbox policy to fall back to a default when the meta contains sandbox state information (codex/sandbox-state-meta).
Affected code locations:
codex-mcp/src/binding.rs:290codex-mcp/src/connection_manager.rs:629
Root cause: Both conversion functions silently discard serialization failures:
meta: result.meta.and_then(|meta| serde_json::to_value(meta).ok()),
If serde_json::to_value(meta) fails (e.g., due to non-UTF-8 strings, unsupported types, or circular references), the meta field is set to None. Downstream consumers that rely on meta for sandbox policy decisions would see no meta and fall back to defaults.
Additionally, the content serialization has a similar issue:
serde_json::to_value(content).unwrap_or_else(|_| JsonValue::String("<content>".to_string()))
If an RMCP content item cannot be serialized, it is silently replaced with the literal string "<content>". The model would see a meaningless placeholder instead of an error message.
Impact:
- Sandbox state meta could be lost, causing the sandbox policy to fall back to a more permissive default
- Tool output content could be replaced with
<content>placeholder, confusing the model
What steps can reproduce the bug?
- Configure an MCP server that returns tool results with non-serializable meta (e.g., containing non-UTF-8 bytes or unsupported types)
- Call the tool from Codex
- The meta is silently dropped and sandbox policy may fall back to default
What is the expected behavior?
The serialization failure should be logged at warn! level so it's observable, and the meta should be preserved if possible (e.g., by converting to a string representation).
Suggested fix
meta: result.meta.and_then(|meta| {
match serde_json::to_value(meta) {
Ok(value) => Some(value),
Err(err) => {
tracing::warn!("failed to serialize MCP tool meta: {err}");
None
}
}
}),
Related
- #33717 — Deferred MCP tool calls drop structuredContent/_meta (similar issue in deferred path)
- #29539 — Windows Computer Use fails: codex/sandbox-state-meta missing sandboxPolicy
Scope
Two call sites in two files. The fix is ~5 lines per call site. No behavioral change for正常 servers — only logging for the failure path.
- Dominant language
- Rust
- Stars
- 125k
- Forks
- 19.5k
- Avg merge
- 1m
- Merged PRs (30d)
- 1k
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from openai/codex
-
enhancement remote
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
-
bug CLI windows-os
Difficulty 2/5 1-3 hours Newbie friendliness 76/100
-
macOS sandbox blocks hw.optional.arm64 sysctl, causing Flutter to misdetect Apple Silicon as x64 Openbug CLI sandbox
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
-
bug CLI TUI
Difficulty 2/5 1-3 hours Newbie friendliness 90/100
-
CLI config enhancement skills
Difficulty 2/5 1-3 hours Newbie friendliness 84/100
Similar issues
-
Difficulty 2/5 1-3 hours Newbie friendliness 86/100
kwakseongjae/auto-hwp#319 ·
-
area:cli bug filter-quality good first issue priority:medium
Difficulty 2/5 1-3 hours Newbie friendliness 84/100
-
Difficulty 1/5 Under an hour Newbie friendliness 72/100
bevyengine/bevy#25861 ·
-
comp-datalake
Difficulty 2/5 1-3 hours Newbie friendliness 88/100
ClickHouse/ClickHouse#121222 ·
-
A-linter
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
oxc-project/oxc#26863 ·