{"record":{"id":"130850729ad68754","repo":"charmbracelet/crush","slug":"failed-to-initialize-crush-server-v","errorCode":null,"errorMessage":"failed to initialize crush server: %v","messagePattern":"failed to initialize crush server: (.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/cmd/root.go","lineNumber":493,"sourceCode":"\t\tslog.Warn(\"Server is shutting down; retrying against a replacement\",\n\t\t\t\"attempt\", attempt+1, \"error\", err)\n\t\tif err := replace(); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\treturn nil, fmt.Errorf(\"failed to create workspace: server kept shutting down\")\n}\n\n// replaceExitingServer waits out the socket of a server that has committed\n// to exiting, then brings up a fresh one.\nfunc replaceExitingServer(cmd *cobra.Command, hostURL *url.URL) error {\n\tif hostURL.Scheme == \"unix\" {\n\t\tif err := awaitSocketGone(cmd.Context(), hostURL); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tif err := spawnAndWaitReady(cmd, hostURL); err != nil {\n\t\treturn fmt.Errorf(\"failed to initialize crush server: %v\", err)\n\t}\n\treturn nil\n}\n\n// ensureServer auto-starts a detached server if the socket file does not\n// exist. When the socket exists, it verifies that the running server\n// version matches the client; on mismatch it shuts down the old server\n// and starts a fresh one.\nfunc ensureServer(cmd *cobra.Command, hostURL *url.URL) error {\n\t// Initialize the persistent log here so stale-socket diagnostics\n\t// emitted before connectToServer runs are captured in the per-host\n\t// server log file. crushlog.Setup uses sync.Once internally, so the\n\t// later call from connectToServer becomes a no-op.\n\tdebug, _ := cmd.Flags().GetBool(\"debug\")\n\tlogFile := filepath.Join(config.GlobalCacheDir(), \"server-\"+safeHostName(hostURL), \"crush.log\")\n\tcrushlog.Setup(logFile, debug)\n\n\tswitch hostURL.Scheme {","sourceCodeStart":475,"sourceCodeEnd":511,"githubUrl":"https://github.com/charmbracelet/crush/blob/7944b8e52225d8805e31eacbf7ef24856b0dfb7a/internal/cmd/root.go#L475-L511","documentation":"replaceExitingServer in internal/cmd/root.go waits for a dying server's unix socket to disappear, then spawns a new server via spawnAndWaitReady. If the new server process fails to start or never reports ready, the error is wrapped as 'failed to initialize crush server: %v'.","triggerScenarios":"spawnAndWaitReady fails: the crush binary/server subcommand errors on startup (port/socket in use, bad config, missing binary on PATH), the ready-signal times out, or the child exits immediately.","commonSituations":"Broken crushrc config crashing the server at startup; another process bound to the socket/port; permission problems executing the server; crashed server leaving a half-bound socket; timeout on slow machines.","solutions":["Read the wrapped %v cause and server logs (`crush logs`) for the exact startup failure","Validate crushrc/crush.json — a bad provider/hook line can crash the server at boot","Remove leftover socket files and kill orphan processes, then retry","Ensure the crush binary is up to date and executable on PATH"],"exampleFix":"// before\ncrushrc: hook \"bad\" { run = \"/nonexistent-script\" }  # server crashes at startup\n// after\n# fix or remove the offending hook block, then:\npkill -f 'crush serve'; rm -f ~/.local/share/crush/crush.sock; crush","handlingStrategy":"fallback","validationCode":"if err := validateConfig(cfgPath); err != nil {\n    return fmt.Errorf(\"refusing to spawn server with invalid config: %w\", err)\n}\nif fi, err := os.Stat(socketPath); err == nil && fi.Mode()&os.ModeSocket != 0 {\n    os.Remove(socketPath)\n}","typeGuard":null,"tryCatchPattern":"if err := spawnAndWaitReady(ctx, hostURL); err != nil {\n    return fmt.Errorf(\"failed to initialize crush server: %w\", err)\n}\n// fallback: run with a temporary empty config to isolate config vs env issues","preventionTips":["Validate crushrc before launching the server","Clear leftover sockets and orphan processes before spawn","Keep the crush binary current and executable","Allow enough time for the ready handshake on slow machines"],"tags":["server","startup","spawn","socket"],"backgroundTag":"server-init-failed","analyzedSha":"7944b8e52225d8805e31eacbf7ef24856b0dfb7a","analyzedAt":"2026-08-29T12:48:59.079Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}