charmbracelet/crush · error
failed to start crush server: %v
Error message
failed to start crush server: %v
What it means
Wraps the error returned by exec.Cmd.Start() when launching a detached Crush server child process. It means the OS refused to spawn the configured binary - typically the executable path does not exist, is not executable, or the working directory is invalid. The wrap preserves the underlying errno (e.g. 'no such file or directory').
Source
Thrown at internal/cmd/root.go:895
stderrPath := filepath.Join(chDir, "stderr.log")
detachProcess(c)
stdout, err := os.Create(stdoutPath)
if err != nil {
return fmt.Errorf("failed to create stdout log file: %v", err)
}
defer stdout.Close()
c.Stdout = stdout
stderr, err := os.Create(stderrPath)
if err != nil {
return fmt.Errorf("failed to create stderr log file: %v", err)
}
defer stderr.Close()
c.Stderr = stderr
if err := c.Start(); err != nil {
return fmt.Errorf("failed to start crush server: %v", err)
}
if err := c.Process.Release(); err != nil {
return fmt.Errorf("failed to detach crush server process: %v", err)
}
return nil
}
func shouldEnableMetrics(cfg *config.Config) bool {
if v, _ := strconv.ParseBool(os.Getenv("CRUSH_DISABLE_METRICS")); v {
return false
}
if v, _ := strconv.ParseBool(os.Getenv("DO_NOT_TRACK")); v {
return false
}
if cfg.Options.DisableMetrics {
return falseView on GitHub (pinned to 7944b8e522)
Solutions
- Verify the crush binary exists and is executable: `which crush && test -x $(which crush)`
- Check that PATH in the spawning environment includes the binary's directory
- Run the command manually to see the underlying errno from the wrapped message
- Reinstall or update crush if the binary was removed by an upgrade
Example fix
// before: binary resolved from an env-var-derived path that may be empty
exe := os.Getenv("CRUSH_BIN")
c := exec.Command(exe, "serve")
// after: resolve explicitly and fail early
exe, err := exec.LookPath("crush")
if err != nil {
return fmt.Errorf("crush binary not found in PATH: %w", err)
}
c := exec.Command(exe, "serve") Defensive patterns
Strategy: validation
Validate before calling
exe, err := exec.LookPath("crush")
if err != nil {
return fmt.Errorf("crush binary not found: %w", err)
}
if info, err := os.Stat(exe); err != nil || info.IsDir() || info.Mode()&0o111 == 0 {
return fmt.Errorf("crush binary missing or not executable: %s", exe)
} Try / catch
if err := startDetachedServer(cmd); err != nil {
var execErr *exec.Error
if errors.As(err, &execErr) {
slog.Error("Server binary not found; check PATH/install", "bin", execErr.Name)
}
return err
} Prevention
- Resolve the binary with exec.LookPath instead of hand-built paths
- Keep PATH intact in service/CI environments (absolute path fallback)
- Verify the executable bit after installs and upgrades
- Check the spawn environment's PATH before spawning
When it happens
Trigger: Calling spawnAndWaitReady -> startDetachedServer where exec.Command points at a non-existent or non-executable binary, the command's Dir is missing, or resource limits (fork failures) prevent process creation.
Common situations: Crush installed outside PATH; PATH stripped in systemd/launchd/cron environments; stale binary after an upgrade or uninstall; minimal containers without the binary.
Related errors
- error starting shell: %w
- failed to detach crush server process: %v
- unsupported by the running server
- clipboard operations are not supported on this platform
- clipboard is empty or holds an unsupported format
AI-assisted analysis of charmbracelet/crush@7944b8e522 (2026-08-29).
Data as JSON: /api/errors/1b8e94b69247defe.
Report an issue: GitHub.