{"record":{"id":"48e99a7c3dd9caca","repo":"aaif-goose/goose","slug":"failed-to-submit-elicitation-response","errorCode":null,"errorMessage":"Failed to submit elicitation response: {}","messagePattern":"Failed to submit elicitation response: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/goose/src/agents/agent.rs","lineNumber":1898,"sourceCode":"                    // The success path returns an empty stream after the MCP\n                    // server receives the user's accept/decline/cancel action.\n                    let response = match action {\n                        ElicitationAction::Accept => ElicitationOutcome::Accept(user_data.clone()),\n                        ElicitationAction::Decline => ElicitationOutcome::Decline,\n                        ElicitationAction::Cancel => ElicitationOutcome::Cancel,\n                        _ => ElicitationOutcome::Cancel,\n                    };\n                    crate::elicitation::complete_elicitation_with_message(\n                        &session_manager,\n                        &session_config.id,\n                        id,\n                        response,\n                        &user_message,\n                    )\n                    .await\n                    .map_err(|e| {\n                        error!(\"Failed to submit elicitation response: {}\", e);\n                        anyhow!(\"Failed to submit elicitation response: {}\", e)\n                    })?;\n                    return Ok(Box::pin(futures::stream::empty()));\n                }\n            }\n        }\n\n        if super::state_machine::enabled()\n            || super::state_machine::bang_shell_command(&message_text_for_trace).is_some()\n        {\n            tracing::info!(\"dispatching reply via experimental state machine\");\n            return self\n                .reply_with_state_machine(user_message, session_config, cancel_token)\n                .await;\n        }\n\n        let message_text = message_text_for_trace;\n\n        let session = session_manager","sourceCodeStart":1880,"sourceCodeEnd":1916,"githubUrl":"https://github.com/aaif-goose/goose/blob/3810898a7447ec3299be72e223d3570a7aabf0ab/crates/goose/src/agents/agent.rs#L1880-L1916","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// Only route a message as an elicitation response if the id is still open:\nlet still_pending = session_manager\n    .action_required()\n    .pending // internal access in embedded builds\n    .read()\n    .await\n    .contains_key(elicitation_id);\nif !still_pending {\n    // deliver as a plain user message instead\n}","typeGuard":"fn elicitation_submit_failed(e: &anyhow::Error) -> bool {\n    e.to_string().contains(\"Failed to submit elicitation response\")\n}","tryCatchPattern":"match complete_elicitation_with_message(/* ... */).await {\n    Err(e) if elicitation_submit_failed(&e) => {\n        let cause = e.source().map(|s| s.to_string()).unwrap_or_default();\n        if cause.contains(\"Request not found\") || cause.contains(\"closed\") {\n            // expired/duplicate answer: fall through to normal reply handling\n        } else {\n            return Err(e); // storage failure — surface it\n        }\n    }\n    Ok(()) => {}\n}","preventionTips":["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"],"tags":["rust","goose","elicitation","reply","race-condition"],"backgroundTag":null,"analyzedSha":"3810898a7447ec3299be72e223d3570a7aabf0ab","analyzedAt":"2026-08-16T10:14:26.282Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}