charmbracelet/crush · error
failed to detach crush server process: %v
Error message
failed to detach crush server process: %v
What it means
Wraps the error from os/exec's Process.Release() after successfully starting the detached server. Release detaches the parent from the child so it won't be reaped; failure usually means the child already exited and was reaped, or the process handle is invalid on this platform.
Source
Thrown at internal/cmd/root.go:899
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 false
}
return true
}
View on GitHub (pinned to 7944b8e522)
Solutions
- Check the server's stderr log file for the real startup failure before Release
- Verify server port/config so the child survives long enough to be released
- Treat Release failure as non-fatal if the readiness probe confirms the server is healthy
- Retry spawnAndWaitReady once, since the failure can be a transient reaping race
Example fix
// before: abort on any Release error
if err := c.Process.Release(); err != nil {
return fmt.Errorf("failed to detach crush server process: %v", err)
}
// after: log but continue if readiness probe succeeds
if err := c.Process.Release(); err != nil {
slog.Warn("Failed to detach crush server process", "error", err)
} Defensive patterns
Strategy: try-catch
Validate before calling
// No practical pre-call validation; verify child health around Release. ready := waitForServerReady(addr, 5*time.Second)
Try / catch
if err := startDetachedServer(cmd); err != nil {
if strings.Contains(err.Error(), "detach") && isServerHealthy(addr) {
slog.Warn("Detach failed but server is healthy; continuing")
return nil
}
return err
} Prevention
- Pair Release with a readiness probe so a failed release of a dead child is caught
- Inspect the child's stderr log when Release fails
- Avoid double-spawning supervisors that race on reaping
- Keep Go and the execution environment updated (platform Release quirks)
When it happens
Trigger: startDetachedServer calls c.Process.Release() after c.Start(); the child exited immediately after start (crash, port conflict, bad config), or the OS already reaped it, making the handle stale.
Common situations: Server crashes on startup so the process is gone by Release time; sandboxed environments limiting process APIs; race between a supervisor and Release.
Related errors
- error starting shell: %w
- failed to start crush server: %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/0837197c68953fc7.
Report an issue: GitHub.