aaif-goose/goose · error
Failed to submit elicitation response: {}
Error message
Failed to submit elicitation response: {} What it means
In Agent's reply handling, when an incoming message is detected as a response to a pending elicitation, complete_elicitation_with_message runs: it claims the pending response (claim_response), appends the elicitation response message to the session, then submits the outcome to the waiting tool. This error wraps any failure in that chain — most often claim_response rejecting the claim (request not found / already completed / channel closed / wrong session) or the session add_message write failing.
Source
Thrown at crates/goose/src/agents/agent.rs:1898
// The success path returns an empty stream after the MCP
// server receives the user's accept/decline/cancel action.
let response = match action {
ElicitationAction::Accept => ElicitationOutcome::Accept(user_data.clone()),
ElicitationAction::Decline => ElicitationOutcome::Decline,
ElicitationAction::Cancel => ElicitationOutcome::Cancel,
_ => ElicitationOutcome::Cancel,
};
crate::elicitation::complete_elicitation_with_message(
&session_manager,
&session_config.id,
id,
response,
&user_message,
)
.await
.map_err(|e| {
error!("Failed to submit elicitation response: {}", e);
anyhow!("Failed to submit elicitation response: {}", e)
})?;
return Ok(Box::pin(futures::stream::empty()));
}
}
}
if super::state_machine::enabled()
|| super::state_machine::bang_shell_command(&message_text_for_trace).is_some()
{
tracing::info!("dispatching reply via experimental state machine");
return self
.reply_with_state_machine(user_message, session_config, cancel_token)
.await;
}
let message_text = message_text_for_trace;
let session = session_managerView on GitHub (pinned to 3810898a74)
Solutions
- Answer pending elicitations promptly, within the waiter's timeout
- Send the response in the same session that issued the request
- If the elicitation already expired, send the content as a normal chat message instead
- Inspect the wrapped {e}: 'Request not found'/'Response channel closed' mean expired; storage errors mean a session-file problem
Defensive patterns
Strategy: try-catch
Validate before calling
// Only route a message as an elicitation response if the id is still open:
let still_pending = session_manager
.action_required()
.pending // internal access in embedded builds
.read()
.await
.contains_key(elicitation_id);
if !still_pending {
// deliver as a plain user message instead
} Type guard
fn elicitation_submit_failed(e: &anyhow::Error) -> bool {
e.to_string().contains("Failed to submit elicitation response")
} Try / catch
match complete_elicitation_with_message(/* ... */).await {
Err(e) if elicitation_submit_failed(&e) => {
let cause = e.source().map(|s| s.to_string()).unwrap_or_default();
if cause.contains("Request not found") || cause.contains("closed") {
// expired/duplicate answer: fall through to normal reply handling
} else {
return Err(e); // storage failure — surface it
}
}
Ok(()) => {}
} Prevention
- Answer elicitations before their timeout and only once
- Keep elicitation ids scoped to the session that issued them
- On expiry, resend the information as a normal message rather than forcing the elicitation path
When it happens
Trigger: Answering an elicitation that already timed out (pending entry removed) or was already answered; sending the elicitation response from a different session_id than the one that issued it; session storage failure while recording the response message.
Common situations: User answers a permission prompt after the tool's wait timed out; UI retry/double-send of the same elicitation answer; resumed session replaying an old elicitation response message as new input.
Related errors
- Request not found: {}
- Timeout waiting for user response
- Could not resolve model config: {error}
- Session {} has no conversation
- Provider not set
AI-assisted analysis of aaif-goose/goose@3810898a74 (2026-08-16).
Data as JSON: /api/errors/48e99a7c3dd9caca.
Report an issue: GitHub.