charmbracelet/crush · error
failed to wait for MCP initialization: %w
Error message
failed to wait for MCP initialization: %w
What it means
Non-interactive runs must have the full MCP tool palette available before a session is created, so RunNonInteractive calls mcp.WaitForInit(ctx) to block until MCP servers finish initializing. If initialization does not settle before the context is done (timeout, cancellation, or an MCP server erroring during startup), this error is returned.
Source
Thrown at internal/app/app.go:320
})
spinner.Start()
}
// Helper function to stop spinner once.
stopSpinner := func() {
if !hideSpinner && spinner != nil {
spinner.Stop()
spinner = nil
}
}
// Non-interactive runs get a single shot at the tool palette, so wait for
// MCP initialization to settle before reading MCP tools. The coordinator
// waits again for the same reason (it is the gate the client/server path
// goes through); doing it here too surfaces the failure before we create a
// session, and lets the UpdateModels below see every MCP tool.
if err := mcp.WaitForInit(ctx); err != nil {
return fmt.Errorf("failed to wait for MCP initialization: %w", err)
}
// force update of agent models before running so mcp tools are loaded
app.AgentCoordinator.UpdateModels(ctx)
defer stopSpinner()
sess, err := app.resolveSession(ctx, continueSessionID, useLast)
if err != nil {
return fmt.Errorf("failed to create session for non-interactive mode: %w", err)
}
if continueSessionID != "" || useLast {
slog.Info("Continuing session for non-interactive run", "session_id", sess.ID)
// If no explicit model override was requested, restore the
// model/provider from the last assistant message in the
// session, provided it is still available.
if largeModel == "" && smallModel == "" {View on GitHub (pinned to 7944b8e522)
Solutions
- Test the MCP server command manually (it must be executable and on PATH)
- Remove or fix broken `mcp` entries in crushrc/crush.json
- Increase the context timeout or MCP init timeout for slow servers
- Run with SLOG_LEVEL=debug to see which MCP client failed
Example fix
// before
{"mcp": {"fs": {"command": "mcp-server-filesystem"}}} // binary not installed
// after
{"mcp": {"fs": {"command": "npx", "args": ["-y", "@modelcontextprotocol/server-filesystem", "/tmp"]}}} Defensive patterns
Strategy: validation
Validate before calling
for name, m := range cfg.MCP {
if m.Command != "" {
if _, err := exec.LookPath(m.Command); err != nil {
return fmt.Errorf("mcp %q command not found: %w", name, err)
}
}
} Try / catch
ctx, cancel := context.WithTimeout(ctx, 60*time.Second)
defer cancel()
if err := app.RunNonInteractive(ctx, w, prompt, "", "", true, "", false); err != nil {
if strings.Contains(err.Error(), "MCP initialization") {
return fmt.Errorf("mcp servers failed to start; check `mcp` config: %w", err)
}
return err
} Prevention
- Smoke-test every MCP server command manually before adding it to config
- Give MCP init a generous timeout in CI pipelines
- Remove unused MCP servers from crushrc to shrink init surface
When it happens
Trigger: An MCP server defined in config fails to launch (bad command, missing binary), hangs during handshake, or ctx is cancelled/times out before all MCP clients initialize.
Common situations: MCP server command typo or not on PATH in crushrc/crush.json; slow-starting MCP server exceeding the run timeout; running `crush run` in CI where MCP servers need network access that is blocked.
Related errors
- agent not ready: %w
- agent coordinator not initialized
- failed to make request: %w
- session ID is required for creating a new file
- mcp '%s' not found in configuration
AI-assisted analysis of charmbracelet/crush@7944b8e522 (2026-08-29).
Data as JSON: /api/errors/153c6ec567ca0670.
Report an issue: GitHub.