{"record":{"id":"835518637062037a","repo":"charmbracelet/crush","slug":"failed-to-create-stderr-log-file-v","errorCode":null,"errorMessage":"failed to create stderr log file: %v","messagePattern":"failed to create stderr log file: (.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/cmd/root.go","lineNumber":889,"sourceCode":"\t// Use context.Background() so the parent's context cancellation does not\n\t// kill the spawned server. detachProcess (Setsid on !windows,\n\t// DETACHED_PROCESS on windows) is what truly detaches the child from\n\t// this process's lifetime.\n\tc := exec.CommandContext(context.Background(), exe, cmdArgs...)\n\tstdoutPath := filepath.Join(chDir, \"stdout.log\")\n\tstderrPath := filepath.Join(chDir, \"stderr.log\")\n\tdetachProcess(c)\n\n\tstdout, err := os.Create(stdoutPath)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to create stdout log file: %v\", err)\n\t}\n\tdefer stdout.Close()\n\tc.Stdout = stdout\n\n\tstderr, err := os.Create(stderrPath)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to create stderr log file: %v\", err)\n\t}\n\tdefer stderr.Close()\n\tc.Stderr = stderr\n\n\tif err := c.Start(); err != nil {\n\t\treturn fmt.Errorf(\"failed to start crush server: %v\", err)\n\t}\n\n\tif err := c.Process.Release(); err != nil {\n\t\treturn fmt.Errorf(\"failed to detach crush server process: %v\", err)\n\t}\n\n\treturn nil\n}\n\nfunc shouldEnableMetrics(cfg *config.Config) bool {\n\tif v, _ := strconv.ParseBool(os.Getenv(\"CRUSH_DISABLE_METRICS\")); v {\n\t\treturn false","sourceCodeStart":871,"sourceCodeEnd":907,"githubUrl":"https://github.com/charmbracelet/crush/blob/7944b8e52225d8805e31eacbf7ef24856b0dfb7a/internal/cmd/root.go#L871-L907","documentation":"Immediately after creating stdout.log, startDetachedServer creates <chDir>/stderr.log to capture the detached server's stderr. A failure here is wrapped as 'failed to create stderr log file' and aborts the spawn, mirroring the stdout failure path.","triggerScenarios":"os.Create(stderrPath) fails for the same class of reasons as stdout.log: unwritable directory, full disk/quota, path component conflict, or sandbox blocking writes — typically right after stdout.log succeeded, so failures here are usually resource exhaustion that hit between the two creates.","commonSituations":"Disk filling up between the two os.Create calls (giant logs); inode exhaustion; security tooling racing file creation; the stderr.log path existing as a directory.","solutions":["Check free disk space and inodes (df; df -i) — two consecutive create failures usually mean exhaustion.","Fix permissions/ownership on the per-host server directory.","Remove a stray directory or immutable file at the stderr.log path (ls -la, chattr -i if needed).","Rotate/clean old stdout.log and stderr.log files that may be consuming the quota."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"if err := checkFreeDisk(chDir, 10*1024*1024); err != nil {\n\treturn fmt.Errorf(\"insufficient space for server logs: %w\", err)\n}\nif info, err := os.Lstat(filepath.Join(chDir, \"stderr.log\")); err == nil && info.IsDir() {\n\treturn fmt.Errorf(\"stderr.log path is a directory\")\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Monitor free disk space and inodes (df; df -i) on the cache filesystem","Clean old server-<host> log files periodically","Verify writability of the server dir before spawning","Check for immutable flags or security tooling interfering with file creation"],"tags":["filesystem","logging","process-spawn","disk-space"],"backgroundTag":"log-file-creation-failed","analyzedSha":"7944b8e52225d8805e31eacbf7ef24856b0dfb7a","analyzedAt":"2026-08-29T12:48:59.079Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}