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

  1. Copy the MCP command from your config and run it manually in a terminal to see the same error output
  2. If using npx/uvx, verify the package name/version exists and the runtime (node/python) is installed
  3. Fix the underlying exec error (chmod +x, correct path, install missing dependency)
  4. 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

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


AI-assisted analysis of charmbracelet/crush@7944b8e522 (2026-08-29). Data as JSON: /api/errors/6e1f731c6251f312. Report an issue: GitHub.