{"record":{"id":"b5a1313790902ded","repo":"zeroclaw-labs/zeroclaw","slug":"rpc-elicitation-create-multi-failed","errorCode":null,"errorMessage":"RPC elicitation/create (multi) failed: {} ({})","messagePattern":"RPC elicitation/create \\(multi\\) failed: (.+?) \\((.+?)\\)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/zeroclaw-runtime/src/rpc/approval_channel.rs","lineNumber":272,"sourceCode":"    async fn request_multi_choice_via_elicitation(\n        &self,\n        question: &str,\n        choices: &[String],\n        min_items: usize,\n        max_items: usize,\n        timeout: Duration,\n    ) -> anyhow::Result<Option<Vec<String>>> {\n        let req = ElicitationRequest {\n            session_id: self.session_id.clone(),\n            mode: ElicitationMode::Form,\n            message: question.to_string(),\n            requested_schema: multi_select_schema(choices, min_items, max_items),\n        };\n        let params = serde_json::to_value(&req)?;\n        let call = self.rpc.request(\"elicitation/create\", params);\n        let response_value = match tokio::time::timeout(timeout, call).await {\n            Ok(Ok(value)) => value,\n            Ok(Err(e)) => anyhow::bail!(\n                \"RPC elicitation/create (multi) failed: {} ({})\",\n                e.message,\n                e.code\n            ),\n            Err(_) => {\n                anyhow::bail!(\"RPC elicitation/create (multi) timed out after {timeout:?}\")\n            }\n        };\n        let parsed: ElicitationResponse = serde_json::from_value(response_value)\n            .map_err(|e| anyhow::Error::msg(format!(\"malformed elicitation response: {e}\")))?;\n        match parsed {\n            ElicitationResponse::Accept { content } => {\n                let texts = decode_multi_select_accept(&content, choices)?;\n                Ok(Some(texts))\n            }\n            ElicitationResponse::Decline | ElicitationResponse::Cancel => Ok(None),\n        }\n    }","sourceCodeStart":254,"sourceCodeEnd":290,"githubUrl":"https://github.com/zeroclaw-labs/zeroclaw/blob/88bb9c8533fc57ed7a03e36ca7c9ed2bf8336dcc/crates/zeroclaw-runtime/src/rpc/approval_channel.rs#L254-L290","documentation":"The multi-select elicitation request sent over JSON-RPC (`elicitation/create`) came back with a protocol-level error object (message + code) from the gateway/client. This is the peer rejecting the request itself — unknown method, rejected schema, unknown session — not the operator declining the form (Decline/Cancel return Ok(None)). The runtime bails with the peer's message and code verbatim so callers can distinguish a broken/unsupported channel from a user decision.","triggerScenarios":"Calling request_multi_choice on a channel whose client does not implement elicitation/create (method-not-found), passing a stale or unknown session_id, or sending a multi_select_schema whose min_items/max_items or enum violates the peer's JSON-schema acceptance rules (e.g. min_items > choices.len(), max_items = 0).","commonSituations":"Client or gateway version predates elicitation support; the session disconnected or expired between channel setup and the ask; a strict validator on the client rejects the schema; only the single-select path is implemented by the connected UI.","solutions":["Check the code in the message: -32601 (method not found) means the peer lacks elicitation support — upgrade the client/gateway or fall back to the plain approval/single-select path.","Verify the session_id on the channel matches a live session on the gateway.","Validate bounds before calling: min_items <= choices.len() and max_items >= min_items, and choices non-empty.","Inspect gateway logs for the rejected elicitation payload if the code is a schema/validation error."],"exampleFix":"// before\nlet picks = channel.request_multi_choice(\"Pick tools\", &choices, 1, 3, timeout).await?;\n\n// after — validate bounds, degrade gracefully when the peer rejects elicitation\nif choices.is_empty() || min_items > choices.len() || max_items < min_items {\n    anyhow::bail!(\"invalid multi-select bounds\");\n}\nlet picks = match channel.request_multi_choice(\"Pick tools\", &choices, 1, 3, timeout).await {\n    Ok(Some(v)) => v,\n    Ok(None) => vec![], // operator declined\n    Err(e) if e.to_string().starts_with(\"RPC elicitation/create\") => {\n        tracing::warn!(\"peer rejected elicitation, denying: {e}\");\n        vec![]\n    }\n    Err(e) => return Err(e),\n};","handlingStrategy":"try-catch","validationCode":"let bounds_ok = !choices.is_empty() && min_items <= choices.len() && max_items >= min_items;\nif !bounds_ok { /* fix inputs before calling */ }","typeGuard":null,"tryCatchPattern":"match channel.request_multi_choice(...).await {\n    Ok(Some(v)) => { /* proceed */ }\n    Ok(None) => { /* operator declined: safe default */ }\n    Err(e) if e.to_string().starts_with(\"RPC elicitation/create (multi) failed\") => {\n        // peer rejected the request: log code/message, degrade to deny or fallback UI\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["Negotiate elicitation capability with the client at session start and fall back to a simpler approval prompt when unsupported.","Validate min_items/max_items against the choice list before issuing the ask.","Keep gateway and client versions aligned; pin a protocol version that includes elicitation/create."],"tags":["rpc","jsonrpc","elicitation","approval","multi-select"],"backgroundTag":"rpc-method-call-failed","analyzedSha":"88bb9c8533fc57ed7a03e36ca7c9ed2bf8336dcc","analyzedAt":"2026-08-23T01:07:41.857Z","schemaVersion":2},"datasetVersion":"2026-08-23T08:06:27.607Z"}