{"record":{"id":"9791cb3d35f57811","repo":"xai-org/grok-build","slug":"32601-9791cb","errorCode":"-32601","errorMessage":"Method not found: {other}","messagePattern":"Method not found: (.+?)","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/codegen/xai-grok-pager/src/headless/ext_protocol.rs","lineNumber":37,"sourceCode":"pub(crate) fn reply_headless_ext_method(args: AcpArgsBox<acp::ExtRequest>) {\n    use xai_grok_tools::implementations::grok_build::ask_user_question::AskUserQuestionExtResponse;\n    use xai_grok_tools::implementations::grok_build::exit_plan_mode::ExitPlanModeExtResponse;\n\n    let method = args.request.method.as_ref();\n    // Known methods are answered without parsing params: even a malformed request gets the policy reply rather than a dropped channel\n    let response = match method {\n        // The model sees the tool's NO_OPERATOR_TEXT (headless sessions are non-interactive), not the interactive \"user declined\" cancel text\n        \"x.ai/ask_user_question\" => ext_response_from(&AskUserQuestionExtResponse::Cancelled),\n        \"x.ai/mcp/elicit\" => {\n            use xai_grok_tools::mcp_elicitation::McpElicitExtResponse;\n            ext_response_from(&McpElicitExtResponse::Cancel)\n        }\n        // The model sees \"Your plan has been approved. You can now start coding.\".\n        \"x.ai/exit_plan_mode\" => ext_response_from(&ExitPlanModeExtResponse {\n            outcome: \"approved\".to_string(),\n            feedback: None,\n        }),\n        other => Err(acp::Error::new(\n            -32601,\n            format!(\"Method not found: {other}\"),\n        )),\n    };\n    args.response_tx.send(response).ok();\n}\n\n/// Coerce a numeric `task_id` (version skew) to a string so it does not fail the decode and leak an untracked background task.\nfn de_task_id<'de, D>(deserializer: D) -> Result<String, D::Error>\nwhere\n    D: serde::Deserializer<'de>,\n{\n    use serde::Deserialize;\n    match serde_json::Value::deserialize(deserializer)? {\n        serde_json::Value::String(s) => Ok(s),\n        serde_json::Value::Number(n) => Ok(n.to_string()),\n        other => Err(serde::de::Error::custom(format!(\n            \"task_id must be a JSON string or number, got {other}\"","sourceCodeStart":19,"sourceCodeEnd":55,"githubUrl":"https://github.com/xai-org/grok-build/blob/bc7f02eddd3d84085849dc19ed216f11c23b0571/crates/codegen/xai-grok-pager/src/headless/ext_protocol.rs#L19-L55","documentation":"The headless ext-method responder (reply_headless_ext_method) answers known interaction methods (x.ai/ask_user_question, x.ai/exit_plan_mode, x.ai/mcp/elicit) with policy replies; any other method gets this JSON-RPC -32601 Method not found error on the response channel. This keeps headless runs from failing the whole turn when the UI is absent.","triggerScenarios":"A reverse ext_method request arrives during a headless run with a method string not in the headless responder's match list — typos, version drift, or a new interactive-only method not yet given a headless policy.","commonSituations":"Server emitting a newly added x.ai/* ext method while the headless protocol layer hasn't been updated; client invoking interactive methods in headless mode.","solutions":["Confirm the method name matches one supported headless (ask_user_question, exit_plan_mode, mcp/elicit)","Update reply_headless_ext_method with a policy reply for the new method if you own the code","Run the client in interactive mode when the method requires a UI","Check client/server version alignment"],"exampleFix":"// before\nother => Err(acp::Error::new(-32601, format!(\"Method not found: {other}\")))\n// after\n\"x.ai/mcp/elicit\" => ext_response_from(&McpElicitExtResponse::default()),\nother => Err(acp::Error::new(-32601, format!(\"Method not found: {other}\")))","handlingStrategy":"try-catch","validationCode":"const HEADLESS_SUPPORTED = [\"x.ai/ask_user_question\", \"x.ai/exit_plan_mode\", \"x.ai/mcp/elicit\"];\nif (!HEADLESS_SUPPORTED.includes(method)) console.warn(`${method} has no headless policy`);","typeGuard":null,"tryCatchPattern":"match response {\n  Err(e) if e.code == -32601 => eprintln!(\"headless mode does not support: {}\", e.message),\n  Ok(resp) => use(resp),\n}","preventionTips":["When adding a new x.ai/* ext method, add a headless policy reply in the same PR","Prefer interactive mode for UI-dependent methods","Keep a capability handshake between client and headless runner"],"tags":["acp","headless","method-not-found","json-rpc"],"backgroundTag":"method-not-found","analyzedSha":"bc7f02eddd3d84085849dc19ed216f11c23b0571","analyzedAt":"2026-08-31T04:59:42.031Z","schemaVersion":2},"datasetVersion":"2026-08-31T09:17:48.483Z"}