{"record":{"id":"93e78ccc87d42229","repo":"Hmbown/CodeWhale","slug":"kimi-formula-web-search-requested-an-unexpected-tool","errorCode":null,"errorMessage":"Kimi Formula web search requested an unexpected tool","messagePattern":"Kimi Formula web search requested an unexpected tool","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/tui/src/client/provider_native_search/kimi.rs","lineNumber":189,"sourceCode":"        };\n\n        reserve_native_search_tool_calls(&mut tool_calls_executed, tool_calls.len())?;\n        messages.push(Value::Object(message.clone()));\n        for tool_call in tool_calls {\n            let id = tool_call\n                .get(\"id\")\n                .and_then(Value::as_str)\n                .context(\"Kimi Formula web-search call omitted id\")?;\n            let function = tool_call\n                .get(\"function\")\n                .and_then(Value::as_object)\n                .context(\"Kimi Formula web-search call omitted function\")?;\n            let name = function\n                .get(\"name\")\n                .and_then(Value::as_str)\n                .context(\"Kimi Formula web-search call omitted function name\")?;\n            if name != WEB_SEARCH_FORMULA_FUNCTION {\n                bail!(\"Kimi Formula web search requested an unexpected tool\");\n            }\n            let arguments = function\n                .get(\"arguments\")\n                .and_then(Value::as_str)\n                .context(\"Kimi Formula web-search call omitted arguments\")?;\n            let _: Value = serde_json::from_str(arguments)\n                .context(\"Kimi Formula web-search arguments were not valid JSON\")?;\n            let fiber = client\n                .post_json(\n                    &fiber_url,\n                    &json!({ \"name\": name, \"arguments\": arguments }),\n                    &[],\n                )\n                .await?;\n            messages.push(json!({\n                \"role\": \"tool\",\n                \"tool_call_id\": id,\n                \"content\": formula_fiber_result(&fiber)?,","sourceCodeStart":171,"sourceCodeEnd":207,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/73e0f67d83c59909b571efdfc88c4bc28c309cb1/crates/tui/src/client/provider_native_search/kimi.rs#L171-L207","documentation":"In the Kimi 'Formula' (K3) web-search flow, the model executes a named web-search function fiber; every function call returned must match WEB_SEARCH_FORMULA_FUNCTION. A call with a different (or missing) function name violates the Formula contract, so the client bails instead of executing an unknown function.","triggerScenarios":"search_formula iterates the model's tool calls and a call's function.name is not WEB_SEARCH_FORMULA_FUNCTION (the call also omits 'function' or 'name' via the earlier .context checks).","commonSituations":"Kimi K3/Formula API change renaming the search function; the request accidentally advertising extra tools; a gateway rewriting tool payloads; routing a non-Formula model to the Formula search path.","solutions":["Verify the request declares only the Formula web-search tool (see formula_web_search_tools) and no other tools","Log the unexpected function name from the response","Update WEB_SEARCH_FORMULA_FUNCTION if the upstream name changed","Retry with a different model or fall back to the non-Formula native search path"],"exampleFix":"// before\nif name != WEB_SEARCH_FORMULA_FUNCTION {\n    bail!(\"Kimi Formula web search requested an unexpected tool\");\n}\n// after\nif name != WEB_SEARCH_FORMULA_FUNCTION {\n    tracing::warn!(name, \"unexpected Kimi Formula tool; ignoring call\");\n    continue;\n}","handlingStrategy":"try-catch","validationCode":"// ensure the Formula request declares only the expected tool\nassert_eq!(request_tools.len(), 1, \"Formula requests must declare exactly one tool\");","typeGuard":"fn is_formula_call(tc: &Value) -> bool {\n    tc.pointer(\"/function/name\").and_then(Value::as_str) == Some(WEB_SEARCH_FORMULA_FUNCTION)\n}","tryCatchPattern":"match provider.search_formula(req).await {\n    Err(e) if e.to_string().contains(\"unexpected tool\") => {\n        log::warn!(\"Formula model requested an unknown function; using builtin search\");\n        provider.search_builtin(req).await\n    }\n    other => other,\n}","preventionTips":["Route only Formula-capable (K3) models to search_formula","Keep the declared tool list to exactly one","Update WEB_SEARCH_FORMULA_FUNCTION promptly when upstream renames the tool"],"tags":["kimi","formula","web-search","tool-calls"],"backgroundTag":"unexpected-api-response-shape","analyzedSha":"73e0f67d83c59909b571efdfc88c4bc28c309cb1","analyzedAt":"2026-09-22T01:30:00.501Z","contentChangedAt":"2026-09-22T01:30:00.501Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}