zeroclaw-labs/zeroclaw · error · anyhow::Error

ACP elicitation/create (multi) failed: {} ({})

Error message

ACP elicitation/create (multi) failed: {} ({})

What it means

The multi-select elicitation/create JSON-RPC call returned a protocol error (message + code). This path runs only for clients advertising elicitation.form; ZeroClaw sends a schema built by multi_select_schema(choices, min_items, max_items) and the client rejected the call itself rather than answering it. The client's code and message are embedded verbatim.

Source

Thrown at crates/zeroclaw-channels/src/acp_channel.rs:388

        }
        if !self.client_caps.form {
            // No legacy fallback for multi-select — session/request_permission
            // is single-select-only. Signal Ok(None) so the caller (poll tool)
            // takes its own non-ACP fallback path.
            return Ok(None);
        }

        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!(
                "ACP elicitation/create (multi) failed: {} ({})",
                e.message,
                e.code
            ),
            Err(_) => {
                anyhow::bail!("ACP 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 =
                    zeroclaw_api::elicitation::decode_multi_select_accept(&content, choices)?;
                Ok(Some(texts))
            }
            ElicitationResponse::Decline | ElicitationResponse::Cancel => Ok(None),

View on GitHub (pinned to 88bb9c8533)

Solutions

  1. Read the embedded (code, message) — it is the client's exact reason for rejecting the multi-select prompt.
  2. Validate the bounds before calling: min_items >= 1, max_items >= min_items, and choices.len() >= min_items.
  3. Verify the session is live and the client truly implements elicitation/create for multi-select schemas.
  4. If multi-select keeps failing, degrade to repeated single-select questions via request_choice.

Example fix

// before
let picks = ch.request_multi_choice(q, &choices, min, max, timeout).await?;

// after
if min == 0 || max < min || choices.len() < min {
    anyhow::bail!("invalid multi-select bounds: min={min} max={max} choices={}", choices.len());
}
let picks = ch.request_multi_choice(q, &choices, min, max, timeout).await?;
Defensive patterns

Strategy: try-catch

Validate before calling

fn valid_multi_bounds(choices: &[String], min: usize, max: usize) -> bool {
    !choices.is_empty() && min >= 1 && max >= min && choices.len() >= min
}

Try / catch

match ch.request_multi_choice(q, &choices, min, max, timeout).await {
    Ok(Some(picks)) => { /* proceed */ }
    Ok(None) => { /* form capability missing or user declined: poll-tool fallback */ }
    Err(e) => {
        tracing::warn!(error = %e, "multi-select prompt failed; degrading to single-select");
        /* fall back to request_choice */
    }
}

Prevention

When it happens

Trigger: request_multi_choice on a form-capable client where elicitation/create fails: the requestedSchema fails client validation (impossible min/max bounds, too few choices), the handler is unimplemented, or the sessionId is stale.

Common situations: min_items/max_items computed from dynamic data producing an invalid range; strict JSON-Schema validation on the client; session reuse after reconnect; capability advertised but not implemented.

Related errors


AI-assisted analysis of zeroclaw-labs/zeroclaw@88bb9c8533 (2026-08-23). Data as JSON: /api/errors/9dad91d264b1c16c. Report an issue: GitHub.