zeroclaw-labs/zeroclaw · warning
RPC elicitation/create timed out after {timeout:?}
Error message
RPC elicitation/create timed out after {timeout:?} What it means
The elicitation approval path wraps the rpc.request("elicitation/create", ...) future in tokio::time::timeout with a caller-supplied duration. If the operator never answers within that window, the timeout arm bails with the elapsed duration. This is an expected operational outcome — an unanswered prompt — distinct from error 878 where the RPC itself errored.
Source
Thrown at crates/zeroclaw-runtime/src/rpc/approval_channel.rs:239
) -> anyhow::Result<Option<String>> {
let req = ElicitationRequest {
session_id: self.session_id.clone(),
mode: ElicitationMode::Form,
message: question.to_string(),
requested_schema: single_select_schema(choices),
};
debug_assert!(
matches!(req.mode, ElicitationMode::Form),
"Phase 1 must not emit URL-mode elicitation"
);
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 failed: {} ({})", e.message, e.code)
}
Err(_) => anyhow::bail!("RPC elicitation/create 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 text = decode_single_select_accept(&content, choices)?;
Ok(Some(text))
}
ElicitationResponse::Decline | ElicitationResponse::Cancel => Ok(None),
}
}
/// Form-mode elicitation multi-select path — same wire shape as
/// `AcpChannel::request_multi_choice`.
async fn request_multi_choice_via_elicitation(
&self,
question: &str,
choices: &[String],View on GitHub (pinned to 88bb9c8533)
Solutions
- Raise the elicitation/approval timeout configuration to match realistic human response time for the deployment
- Verify the client actually surfaces the prompt (check notification settings, visible session)
- Design callers to treat timeout as non-consent: catch this bail and take the safe default/deny path
- For unattended flows, pre-configure auto-approval policies so human prompts never block
Example fix
// before: timeout treated as a hard error
let ans = channel.request_choice(&q, &choices, Duration::from_secs(30)).await?;
// after: timeout degrades to deny
match channel.request_choice(&q, &choices, Duration::from_secs(120)).await {
Ok(Some(c)) => c,
other => { tracing::warn!("no operator answer, denying"); deny() }
} Defensive patterns
Strategy: fallback
Try / catch
match channel.request_choice(&q, &choices, timeout).await {
Ok(Some(c)) => c,
Ok(None) => default_choice(),
Err(e) if e.to_string().contains("timed out") => {
// operator absent: take the safe default/deny and continue — never block the runtime
default_choice()
}
Err(e) => Err(e),
} Prevention
- Size approval timeouts for real human response times in that deployment (minutes, not seconds)
- Verify clients visibly surface elicitation prompts before relying on them for approvals
- Use auto-approval policies for unattended flows so timeouts never stall automation
- Alert on frequent approval timeouts — they usually mean prompts are not reaching a human
When it happens
Trigger: Operator is away or misses the prompt before the timeout expires; the client renders the elicitation form but nobody interacts; timeout configured too aggressively for human response times; UI swallowed the prompt (notification lost, window hidden) so no answer ever arrives.
Common situations: Unattended automation hitting approval gates; timeouts tuned for fast acks applied to rare high-stakes approvals; first-time users unfamiliar with the prompt UI; long-running sessions where prompts queue behind other activity.
Understand the failure class
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
Related errors
- RPC elicitation/create failed: {} ({})
- ACP elicitation/create timed out after {timeout:?}
- ACP elicitation/create (multi) timed out after {timeout:?}
- RPC elicitation/create (multi) timed out after {timeout:?}
- ACP elicitation/create failed: {} ({})
AI-assisted analysis of zeroclaw-labs/zeroclaw@88bb9c8533 (2026-08-23).
Data as JSON: /api/errors/bb50ccb38fcad88f.
Report an issue: GitHub.