aaif-goose/goose · error

Tool call request not found for elicitation: {}

Error message

Tool call request not found for elicitation: {}

What it means

request_elicitation looks up an mpsc sender registered under the key (session_id, tool_call_request_id) in action_required_senders; if no entry exists it fails immediately with this message. The registration is created when a tool call action-required stream is set up, so this error means the elicitation references a tool call that has no live message stream in that session.

Source

Thrown at crates/goose/src/action_required_manager.rs:78

    }

    pub(crate) async fn request_and_wait(
        &self,
        session_id: String,
        tool_call_request_id: String,
        message: String,
        schema: Value,
        timeout_duration: Duration,
    ) -> Result<ElicitationOutcome> {
        let sender = self
            .action_required_senders
            .lock()
            .await
            .get(&(session_id.clone(), tool_call_request_id.clone()))
            .cloned();

        let Some(sender) = sender else {
            return Err(anyhow::anyhow!(
                "Tool call request not found for elicitation: {}",
                tool_call_request_id
            ));
        };

        let id = Uuid::new_v4().to_string();
        let (tx, rx) = tokio::sync::oneshot::channel();
        let pending_request = PendingRequest {
            session_id: session_id.clone(),
            response_tx: Some(tx),
        };
        let pending_request = Arc::new(Mutex::new(pending_request));

        self.pending
            .write()
            .await
            .insert(id.clone(), Arc::clone(&pending_request));

View on GitHub (pinned to 3810898a74)

Solutions

  1. Verify the tool_call_request_id belongs to an in-flight tool call in the same session before eliciting
  2. Close/discard elicitation dialogs when the owning session or tool call completes
  3. Re-issue the tool call if the elicitation is still relevant, producing a fresh request id with a live sender
Defensive patterns

Strategy: validation

Validate before calling

// before eliciting, confirm the tool call still has a live sender for this session
let known: Vec<_> = manager.active_tool_call_ids(session_id).await; // expose keys for introspection
if !known.contains(&tool_call_request_id) {
    return Err(anyhow::anyhow!("tool call {tool_call_request_id} not active in session"));
}

Try / catch

match manager.request_elicitation(sid, tcid, msg, schema, d).await {
    Err(e) if e.to_string().contains("not found for elicitation") => {
        tracing::warn!(%e, "stale tool call; re-issue it");
        retry_tool_call().await
    }
    r => r,
}

Prevention

When it happens

Trigger: Responding to an elicitation for a tool_call_request_id from a different session, one whose session already ended and deregistered its sender, or a stale/expired request id retained by the client.

Common situations: Client keeps an old dialog open after the session restarted; tool call finished and its stream was removed, then a late elicitation response arrives; session ids mixed up in a multi-session client.

Related errors


AI-assisted analysis of aaif-goose/goose@3810898a74 (2026-08-16). Data as JSON: /api/errors/5afd2aac12f71116. Report an issue: GitHub.