aaif-goose/goose · error
Failed to start extension: {}
Error message
Failed to start extension: {} What it means
add_and_persist_extensions forwards each ExtensionConfig to Agent::add_extension, which spawns the stdio MCP server process. Any startup failure — spawn error, immediate exit, or failed MCP handshake — is wrapped as 'Failed to start extension: {e}' with the underlying cause in the message.
Source
Thrown at crates/goose-cli/src/session/mod.rs:451
ExtensionConfig::Builtin {
name: extension_name.to_string(),
display_name: None,
timeout: None,
bundled: None,
description: extension_name.to_string(),
available_tools: Vec::new(),
}
}
})
.collect()
}
async fn add_and_persist_extensions(&mut self, configs: Vec<ExtensionConfig>) -> Result<()> {
for config in configs {
self.agent
.add_extension(config, &self.session_id)
.await
.map_err(|e| anyhow::anyhow!("Failed to start extension: {}", e))?;
}
self.invalidate_completion_cache().await;
Ok(())
}
pub async fn add_extension(&mut self, extension_command: String) -> Result<()> {
let config = Self::parse_stdio_extension(&extension_command)?;
self.add_and_persist_extensions(vec![config]).await
}
pub async fn add_streamable_http_extension(&mut self, extension_url: String) -> Result<()> {
let config = Self::parse_streamable_http_extension(
&extension_url,
goose::config::DEFAULT_EXTENSION_TIMEOUT,
);
self.add_and_persist_extensions(vec![config]).awaitView on GitHub (pinned to 3810898a74)
Solutions
- Run the extension command by hand in the same shell and confirm it starts and stays up
- Install the missing runtime or package dependencies the command needs
- Use an absolute path for the command when PATH resolution differs
- Re-add the extension with corrected KEY=VALUE env prefixes
Example fix
# before --with-extension my-mcp-server # not on PATH # after --with-extension node /home/me/my-mcp-server/build/index.js
Defensive patterns
Strategy: validation
Validate before calling
use std::process::Command;
fn extension_command_runs(cmd: &str) -> bool {
let mut parts = cmd.split_whitespace();
match parts.next() {
Some(bin) => Command::new(bin).output().is_ok(),
None => false,
}
} Try / catch
if let Err(e) = session.add_extension(cmd.to_string()).await {
if e.to_string().contains("Failed to start extension") {
eprintln!("extension '{}' failed to start; check PATH and dependencies", cmd);
}
return Err(e);
} Prevention
- Test-run the extension command in the same shell before adding it to goose
- Prefer absolute paths for extension binaries
- Ensure the runtime (node, python, uvx) and dependencies are installed and on PATH
When it happens
Trigger: goose add-extension / --with-extension with a command not on PATH, not executable, missing its runtime (node/python), or an MCP server that crashes before the initialize handshake completes.
Common situations: Wrong interpreter path; node_modules missing after a fresh clone; PATH differing between the user's shell and goose's environment; npx fetch failures offline.
Related errors
- ACP URL is not available
- Resource '${fallbackUri}' returned no contents
- Unsupported extension type for ACP: ${config.type}
- Goose binary not found in any of the possible paths: ${possi
- GOOSE_SERVER__SECRET_KEY is required for goose serve
AI-assisted analysis of aaif-goose/goose@3810898a74 (2026-08-16).
Data as JSON: /api/errors/a21df8d2f31a6cc4.
Report an issue: GitHub.