zeroclaw-labs/zeroclaw · error
RPC elicitation/create (multi) failed: {} ({})
Error message
RPC elicitation/create (multi) failed: {} ({}) What it means
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.
Source
Thrown at crates/zeroclaw-runtime/src/rpc/approval_channel.rs:272
async fn request_multi_choice_via_elicitation(
&self,
question: &str,
choices: &[String],
min_items: usize,
max_items: usize,
timeout: Duration,
) -> anyhow::Result<Option<Vec<String>>> {
let req = ElicitationRequest {
session_id: self.session_id.clone(),
mode: ElicitationMode::Form,
message: question.to_string(),
requested_schema: multi_select_schema(choices, min_items, max_items),
};
let params = serde_json::to_value(&req)?;
let call = self.rpc.request("elicitation/create", params);
let response_value = match tokio::time::timeout(timeout, call).await {
Ok(Ok(value)) => value,
Ok(Err(e)) => anyhow::bail!(
"RPC elicitation/create (multi) failed: {} ({})",
e.message,
e.code
),
Err(_) => {
anyhow::bail!("RPC elicitation/create (multi) timed out after {timeout:?}")
}
};
let parsed: ElicitationResponse = serde_json::from_value(response_value)
.map_err(|e| anyhow::Error::msg(format!("malformed elicitation response: {e}")))?;
match parsed {
ElicitationResponse::Accept { content } => {
let texts = decode_multi_select_accept(&content, choices)?;
Ok(Some(texts))
}
ElicitationResponse::Decline | ElicitationResponse::Cancel => Ok(None),
}
}View on GitHub (pinned to 88bb9c8533)
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.
Example fix
// before
let picks = channel.request_multi_choice("Pick tools", &choices, 1, 3, timeout).await?;
// after — validate bounds, degrade gracefully when the peer rejects elicitation
if choices.is_empty() || min_items > choices.len() || max_items < min_items {
anyhow::bail!("invalid multi-select bounds");
}
let picks = match channel.request_multi_choice("Pick tools", &choices, 1, 3, timeout).await {
Ok(Some(v)) => v,
Ok(None) => vec![], // operator declined
Err(e) if e.to_string().starts_with("RPC elicitation/create") => {
tracing::warn!("peer rejected elicitation, denying: {e}");
vec![]
}
Err(e) => return Err(e),
}; Defensive patterns
Strategy: try-catch
Validate before calling
let bounds_ok = !choices.is_empty() && min_items <= choices.len() && max_items >= min_items;
if !bounds_ok { /* fix inputs before calling */ } Try / catch
match channel.request_multi_choice(...).await {
Ok(Some(v)) => { /* proceed */ }
Ok(None) => { /* operator declined: safe default */ }
Err(e) if e.to_string().starts_with("RPC elicitation/create (multi) failed") => {
// peer rejected the request: log code/message, degrade to deny or fallback UI
}
Err(e) => return Err(e),
} Prevention
- 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.
When it happens
Trigger: 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).
Common situations: 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.
Related errors
- ACP elicitation/create (multi) failed: {} ({})
- RPC elicitation/create (multi) timed out after {timeout:?}
- ACP elicitation/create failed: {} ({})
- ACP elicitation/create (multi) timed out after {timeout:?}
- ACP returned unexpected permission outcome: {other}
AI-assisted analysis of zeroclaw-labs/zeroclaw@88bb9c8533 (2026-08-23).
Data as JSON: /api/errors/b5a1313790902ded.
Report an issue: GitHub.