{"record":{"id":"0e9ca5eecb96e7e5","repo":"aaif-goose/goose","slug":"requested-mode-s-not-offered-by-agent-avail","errorCode":null,"errorMessage":"Requested mode(s) [{}] not offered by agent. Available modes: {}","messagePattern":"Requested mode\\(s\\) \\[(.+?)\\] not offered by agent\\. Available modes: (.+?)","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/goose/src/acp/provider.rs","lineNumber":1463,"sourceCode":"\nasync fn apply_session_mode(\n    config: &AcpProviderConfig,\n    goose_mode: &Arc<Mutex<GooseMode>>,\n    cx: &ConnectionTo<Agent>,\n    session: NewSessionResponse,\n) -> Result<NewSessionResponse> {\n    let current_mode = goose_mode.lock().ok().map(|mode| *mode);\n    let candidates = initial_mode_candidates(config, current_mode);\n\n    if let Some(modes) = session.modes.as_ref() {\n        if !candidates.is_empty() {\n            let Some(mode_id) = select_mode_id(&candidates, Some(modes)) else {\n                let available: Vec<String> = modes\n                    .available_modes\n                    .iter()\n                    .map(|mode| mode.id.0.to_string())\n                    .collect();\n                return Err(anyhow::anyhow!(\n                    \"Requested mode(s) [{}] not offered by agent. Available modes: {}\",\n                    candidates.join(\", \"),\n                    available.join(\", \")\n                ));\n            };\n            if modes.current_mode_id.0.as_ref() != mode_id.as_str() {\n                let _: SetSessionModeResponse = cx\n                    .send_request(SetSessionModeRequest::new(\n                        session.session_id.clone(),\n                        mode_id,\n                    ))\n                    .block_task()\n                    .await\n                    .map_err(|err| {\n                        anyhow::anyhow!(\n                            \"ACP agent rejected {}: {err}\",\n                            AGENT_METHOD_NAMES.session_set_mode\n                        )","sourceCodeStart":1445,"sourceCodeEnd":1481,"githubUrl":"https://github.com/aaif-goose/goose/blob/3810898a7447ec3299be72e223d3570a7aabf0ab/crates/goose/src/acp/provider.rs#L1445-L1481","documentation":"When a session exposes modes, apply_session_mode computes candidate mode ids from the provider config plus the current goose mode, then calls select_mode_id to intersect them with the agent's advertised available_modes. If the intersection is empty, this error lists the requested candidates and the agent's actual available mode ids so the mismatch is visible.","triggerScenarios":"The provider config requests a mode (e.g. 'approval') or the active goose mode maps to an id the agent does not offer — the agent only exposes ids like 'primary'/'edit', or a custom agent uses entirely different mode names.","commonSituations":"Setting a mode override in config for one agent and reusing that config with another agent; agents renaming modes between versions; a custom ACP agent with bespoke mode ids.","solutions":["Pick one of the ids from the 'Available modes' list in the error and use it as the requested mode","Remove the mode override from the provider config so the default/current mode is used without a set_mode call","If the agent should offer the mode, update/extend the agent to advertise it in its modes.available_modes"],"exampleFix":"# before\nmode: approval            # not offered by this agent\n\n# after\nmode: primary             # taken from the error's Available modes list","handlingStrategy":"validation","validationCode":"fn pick_mode<'a>(candidates: &[String], modes: &'a SessionModes) -> Option<&'a str> {\n    modes\n        .available_modes\n        .iter()\n        .map(|m| m.id.0.as_str())\n        .find(|id| candidates.iter().any(|c| c == id))\n}\n\nassert!(pick_mode(&candidates, modes).is_some(), \"mode not offered by agent\");","typeGuard":null,"tryCatchPattern":"match apply_session_mode(config, &mode, cx, session).await {\n    Err(e) if e.to_string().contains(\"not offered by agent\") => {\n        tracing::warn!(%e, \"falling back to agent default mode\");\n        Ok(session) // proceed with current_mode_id\n    }\n    r => r,\n}","preventionTips":["Read available_modes from the session response before configuring a mode","Do not copy mode settings between different agents"],"tags":["acp","session","mode","config","capability"],"backgroundTag":null,"analyzedSha":"3810898a7447ec3299be72e223d3570a7aabf0ab","analyzedAt":"2026-08-16T10:14:26.282Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}