Bug: MCP tool-call meta serialization failure silently drops sandbox state

Open Beginner friendly
#35,451 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
2/5
Estimated time
1-3 hours
Newbie friendliness
78/100
Issue type
Bug
Clarity
Clearly specified
Activity status
Quiet
Tech stack
rust
Domain
api, cli

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

bug CLI mcp sandbox
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:290
  • codex-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:

  1. Sandbox state meta could be lost, causing the sandbox policy to fall back to a more permissive default
  2. Tool output content could be replaced with <content> placeholder, confusing the model
What steps can reproduce the bug?
  1. Configure an MCP server that returns tool results with non-serializable meta (e.g., containing non-UTF-8 bytes or unsupported types)
  2. Call the tool from Codex
  3. 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

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from openai/codex

All issues in openai/codex

Similar issues

More Rust issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.