charmbracelet/crush · error
%w: %s
Error message
%w: %s
What it means
stdioCheck re-runs a stdio MCP server's command with a 5-second timeout as a health probe. If the process exits non-zero before the deadline, the exec error is wrapped together with the process's combined stdout/stderr output so the user sees why the server binary failed. Timeout-expired probes are treated as success (server may just be long-running).
Source
Thrown at internal/agent/tools/mcp/init.go:1330
}
func stdioCheck(old *exec.Cmd) error {
ctx, cancel := context.WithTimeout(context.Background(), time.Second*5)
defer cancel()
// old.Args includes argv0 as the first element; exec.CommandContext
// prepends old.Path as argv0, so we must skip it to avoid duplication
// (e.g. "npx npx -y pkg" instead of "npx -y pkg").
args := old.Args
if len(args) > 0 {
args = args[1:]
}
cmd := exec.CommandContext(ctx, old.Path, args...)
cmd.Env = old.Env
out, err := cmd.CombinedOutput()
if err == nil || errors.Is(ctx.Err(), context.DeadlineExceeded) {
return nil
}
return fmt.Errorf("%w: %s", err, string(out))
}
View on GitHub (pinned to 7944b8e522)
Solutions
- Copy the MCP command from your config and run it manually in a terminal to see the same error output
- If using npx/uvx, verify the package name/version exists and the runtime (node/python) is installed
- Fix the underlying exec error (chmod +x, correct path, install missing dependency)
- If the command is a long-lived server that prints errors but keeps running, ensure it exits 0 during startup or suppress the probe by fixing the noisy early exit
Example fix
// before (crushrc)
mcp fetch {
type stdio
command "uvx"
args ["fetch-server-mcp"] # package name wrong
}
// after
mcp fetch {
type stdio
command "uvx"
args ["mcp-server-fetch"]
} Defensive patterns
Strategy: validation
Validate before calling
// probe the stdio command exactly as the library will
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
out, err := exec.CommandContext(ctx, cmd, args...).CombinedOutput()
if err != nil && ctx.Err() != context.DeadlineExceeded {
return fmt.Errorf("stdio command fails: %v: %s", err, out)
} Try / catch
// treat startup probe failure as a config problem, surface the output
if err := stdioCheck(serverCmd); err != nil {
return fmt.Errorf("MCP stdio server %q failed to start: %w", name, err)
} Prevention
- Run every npx/uvx MCP command manually once before adding it to config
- Pin package versions (npx -y pkg@1.2.3) to avoid surprise failures
- Ensure the runtime interpreter exists in the PATH of the environment running Crush
When it happens
Trigger: Configured stdio command (`npx -y pkg`, `uvx ...`, a local binary) fails immediately: binary not found, script crashes, missing arguments, bad interpreter, or node/python dependency resolution fails with an error printed to stdout/stderr.
Common situations: Package not published or wrong version in npx/uvx invocation; shebang or permissions broken on a local script; runtime (node/python) not installed; network failure downloading the package on first run.
Related errors
- ripgrep: %w
- interactive OAuth authorization required
- failed to start OAuth callback listener: all candidate ports
- OAuth callback listener closed
- ripgrep: %w\n%s
AI-assisted analysis of charmbracelet/crush@7944b8e522 (2026-08-29).
Data as JSON: /api/errors/6e1f731c6251f312.
Report an issue: GitHub.