aaif-goose/goose · critical · anyhow::Error
ACP initialize failed: {err}
Error message
ACP initialize failed: {err} What it means
The JSON-RPC 'initialize' request to the ACP agent failed at the protocol layer. The request is sent with ProtocolVersion::LATEST and the client capabilities right after the child spawns; failure means the agent process answered with an error, closed the connection, or the transport broke before/while responding. The message is both returned as the init error and surfaced to the caller as an internal_error.
Source
Thrown at crates/goose/src/acp/provider.rs:1254
cx: ConnectionTo<Agent>,
rx: &mut mpsc::Receiver<ClientRequest>,
prompt_response_tx: Arc<Mutex<Option<mpsc::Sender<AcpUpdate>>>>,
init_tx: oneshot::Sender<Result<InitializeResponse>>,
) -> Result<(), agent_client_protocol::Error> {
let mut init_tx = Some(init_tx);
let client_capabilities = ClientCapabilities::new();
let init_response: InitializeResponse = cx
.send_request(
InitializeRequest::new(ProtocolVersion::LATEST)
.client_capabilities(client_capabilities),
)
.block_task()
.await
.map_err(|err| {
let message = format!("ACP {} failed: {err}", AGENT_METHOD_NAMES.initialize);
if let Some(tx) = init_tx.take() {
let _ = tx.send(Err(anyhow::anyhow!(message.clone())));
}
agent_client_protocol::Error::internal_error().data(message)
})?;
let supports_close = init_response
.agent_capabilities
.session_capabilities
.close
.is_some();
let supports_load = init_response.agent_capabilities.load_session;
let mcp_capabilities = init_response.agent_capabilities.mcp_capabilities.clone();
if let Some(tx) = init_tx.take() {
log_undelivered(tx.send(Ok(init_response)), AGENT_METHOD_NAMES.initialize);
}
let mut session_ids: Vec<SessionId> = Vec::new();
while let Some(request) = rx.recv().await {View on GitHub (pinned to 3810898a74)
Solutions
- Run the agent command manually with the same args/env and watch stderr; ensure nothing but JSON-RPC goes to stdout (route logs to stderr)
- For npx-based agents, pre-install the package (npm i -g) so first-run download output cannot corrupt the stream
- Align versions: update goose and the agent so both use a compatible agent-client-protocol crate
- Set any env vars the agent requires at startup via the provider's env map
Example fix
# before (agent code pollutes stdout)
console.log('agent starting');
# after
console.error('agent starting'); Defensive patterns
Strategy: try-catch
Try / catch
match provider.initialize().await {
Ok(resp) => resp,
Err(e) if e.to_string().contains("initialize") => {
tracing::error!(%e, "ACP agent failed to initialize; check agent stderr and stdout hygiene");
return Err(e);
}
Err(e) => return Err(e),
} Prevention
- Keep agent logging strictly on stderr; stdout must carry only ACP JSON-RPC
- Pin compatible versions of goose and the agent's agent-client-protocol
- Pre-install npx-based agents to keep first-run output off stdout
When it happens
Trigger: The agent process prints non-protocol text to stdout (banners, logs, compile output) corrupting the JSON-RPC stream; the agent exits or crashes immediately after spawn (bad args, missing runtime like an unavailable node version); a protocol version or schema mismatch between goose and the agent.
Common situations: Wrapping a CLI that logs to stdout instead of stderr, npx downloading/caching output polluting stdout on first run, agent built against an older agent_client_protocol version, or the agent exiting due to a missing env var needed at startup.
Related errors
- ACP URL is not available
- Message with id ${messageId} not found in current messages
- Cannot update message while prompt is active
- Cannot update message because the active prompt could not be
- Resource '${fallbackUri}' returned no contents
AI-assisted analysis of aaif-goose/goose@3810898a74 (2026-08-16).
Data as JSON: /api/errors/d272fbfc9e391cc0.
Report an issue: GitHub.