openai/codex · critical
generated skill tool schema should serialize: {err}
Error message
generated skill tool schema should serialize: {err} What it means
This panic sits in schema_for (codex-rs/ext/skills/src/tools/schema.rs:22-23): after schemars generates a root JSON Schema, serde_json::to_value serializes it, and a serialization failure aborts with this message. It is an internal-invariant panic - schemars' Schema type serializes to JSON by construction, so with released crates this path is effectively unreachable. Encountering it points at a broken environment (corrupted build artifacts, or a patched/forked schemars or serde_json in the dependency graph) rather than any caller mistake.
Source
Thrown at codex-rs/ext/skills/src/tools/schema.rs:23
pub(super) fn input_schema_for<T: JsonSchema>() -> Value {
schema_for::<T>(/*option_add_null_type*/ false)
}
pub(super) fn output_schema_for<T: JsonSchema>() -> Value {
schema_for::<T>(/*option_add_null_type*/ true)
}
fn schema_for<T: JsonSchema>(option_add_null_type: bool) -> Value {
let schema = SchemaSettings::draft2019_09()
.with(|settings| {
settings.inline_subschemas = true;
settings.option_add_null_type = option_add_null_type;
})
.into_generator()
.into_root_schema_for::<T>();
let schema_value = serde_json::to_value(schema)
.unwrap_or_else(|err| panic!("generated skill tool schema should serialize: {err}"));
let Value::Object(mut schema_object) = schema_value else {
unreachable!("root tool schema must be an object");
};
let mut tool_schema = Map::new();
for key in [
"properties",
"required",
"type",
"additionalProperties",
"$defs",
"definitions",
] {
if let Some(value) = schema_object.remove(key) {
tool_schema.insert(key.to_string(), value);
}
}
Value::Object(tool_schema)View on GitHub (pinned to 339751715c)
Solutions
- Run cargo clean and rebuild to clear corrupted incremental artifacts
- Check Cargo.toml/Cargo.lock for [patch] sections or forked schemars/serde_json versions; pin the stock crates
- If it reproduces on a clean build with stock dependencies, capture the {err} payload and file a codex-rs issue - it is a library-level bug
Defensive patterns
Strategy: try-catch
Try / catch
let built = std::panic::catch_unwind(|| {
skill_function_tool::<MyArgs, MyOut>("my_tool", "desc")
});
if built.is_err() {
tracing::error!("skill schema generation panicked; skipping tool");
} Prevention
- Treat this panic as an environment signal - cargo clean before debugging code
- Keep schemars and serde_json unpatched and single-sourced in Cargo.lock
- Wrap skill tool registration in catch_unwind when it runs inside a long-lived host process
When it happens
Trigger: serde_json::to_value fails on a schemars root schema - the only realistic causes are a dependency fork/patch emitting non-serializable content or corrupted incremental-build artifacts. Fires at skill tool registration time, deterministically per build.
Common situations: A [patch] entry or git dependency swapping schemars/serde_json for a modified version; a stale or corrupt target/ directory after an interrupted build; practically never on a clean stock build.
Related errors
- generated input schema for {name} should parse: {err}
- root tool schema must be an object
- plugin cache root should be absolute: {err}
- failed to parse app config for selected plugin `{plugin_id}`
- failed to parse MCP config for selected plugin `{plugin_id}`
AI-assisted analysis of openai/codex@339751715c (2026-08-25).
Data as JSON: /api/errors/088106e92113f7aa.
Report an issue: GitHub.