Hmbown/CodeWhale · error
Moonshot function parameters failed safe compatibility…
Error message
Moonshot function parameters failed safe compatibility validation: {error} What it means
Before a request goes to Moonshot/Kimi, sanitize_for_kimi_parameters rewrites every tool's function.parameters into MFJS (Moonshot's JSON Schema subset): the root must flatten to type:"object", internal $ref chains are inlined, unsupported keywords are translated or dropped. Constructs the pass cannot transform safely (see the KimiParameterSchemaError enum: unsupported nested allOf, cyclic root reference, const literals, invalid nullable, root not an object schema, resource limits) abort the whole request with this wrapper message. The diagnostic deliberately omits the schema and $ref contents because MCP-supplied tool schemas may contain private data.
Solutions
- Read the KimiParameterSchemaError text after the colon - it names the exact rejected construct (e.g. 'unsupported nested allOf composition').
- Rewrite the tool's parameters as a plain {"type":"object","properties":{...}} root, flattening composition by hand.
- Inline $defs/$ref into literal subschemas before the tool reaches the Kimi route.
- Replace const literals with single-value enums and remove conflicting constraints.
- Route that tool to a provider whose schema rules accept the original shape, or report the schema shape (not contents) upstream.
Example fix
// before - root composition, rejected: "root must be a JSON object schema"
{ "anyOf": [ { "type": "object", "properties": { "path": { "type": "string" } } },
{ "type": "object", "properties": { "id": { "type": "string" } } } ] }
// after - plain object root, composition flattened manually
{ "type": "object",
"properties": { "path": { "type": "string" }, "id": { "type": "string" } } }
Defensive patterns
Strategy: validation
Validate before calling
// Rust: dry-run every tool schema against the Kimi sanitizer before building the request
let mut incompatible = Vec::new();
for tool in &catalog {
let mut candidate = tool.function.parameters.clone();
if crate::tools::schema_sanitize::sanitize_for_kimi_parameters(&mut candidate).is_err() {
incompatible.push(tool.name.clone());
}
}
if !incompatible.is_empty() {
anyhow::bail!("tools not MFJS-compatible: {}", incompatible.join(", "));
}
Type guard
fn is_kimi_compatible(params: &serde_json::Value) -> bool {
let mut candidate = params.clone();
crate::tools::schema_sanitize::sanitize_for_kimi_parameters(&mut candidate).is_ok()
}
Prevention
- Author function.parameters as plain {"type":"object","properties":{...}} roots - no root anyOf/allOf/$ref.
- Inline $defs and $ref chains before exposing tools to Kimi routes.
- Avoid const and nested allOf; use single-value enums and flattened properties.
- Run the sanitizer as a registration-time check for MCP tools, not at request time.
When it happens
Trigger: A tool whose parameters root is anyOf/allOf/$ref instead of a plain type:"object"; nested allOf composition anywhere in the schema; cyclic, unresolved, or non-object root $refs (including $defs chains); const literals or conflicting enum/const constraints; invalid nullable markers; schemas exceeding MFJS resource limits.
Common situations: Registering MCP servers that export rich Draft-2020-12 schemas generated from zod/typebox; tools authored for looser OpenAI routes reused on a Kimi route; a codewhale upgrade that tightened MFJS validation.
Related errors
- .inputSchema must be a valid object-shaped MCP input schema
- Moonshot/Kimi API key not found. Get a key
- 1
- A pinned task provider requires an explicit model
- A positive pull request number is required
AI-assisted analysis of Hmbown/CodeWhale@0c42157ee5 (2026-08-20).
Data as JSON: /api/errors/64974ef8147a4bb5.
Report an issue: GitHub.
Appendix: source
Thrown at crates/tui/src/client/chat.rs:932
};
mirror_minimax_reasoning_details_for_messages(messages);
}
fn sanitize_moonshot_chat_tools(chat_tools: &mut [Value]) -> Result<()> {
for tool in chat_tools {
let Some(function) = tool
.as_object_mut()
.and_then(|tool| tool.get_mut("function"))
.and_then(Value::as_object_mut)
else {
continue;
};
let Some(parameters) = function.get_mut("parameters") else {
continue;
};
let note = crate::tools::schema_sanitize::sanitize_for_kimi_parameters(parameters)
.map_err(|error| {
anyhow::anyhow!(
"Moonshot function parameters failed safe compatibility validation: {error}"
)
})?;
if let Some(note) = note {
let description = function
.get("description")
.and_then(Value::as_str)
.unwrap_or_default();
let description = if description.is_empty() {
note
} else {
format!("{description} {note}")
};
function.insert("description".to_string(), json!(description));
}
}
Ok(())
}View on GitHub (pinned to 0c42157ee5)