{"record":{"id":"c2eef574f80b613d","repo":"gastownhall/beads","slug":"writing-pid-file-w","errorCode":null,"errorMessage":"writing PID file: %w","messagePattern":"writing PID file: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/doltserver/doltserver.go","lineNumber":1485,"sourceCode":"\t\t\t// detected here but never auto-repaired — reinitializing .dolt is\n\t\t\t// destructive, so repair stays behind explicit bd doctor --fix.\n\t\t\tif dirs, detErr := detectCorruptManifest(beadsDir, doltDir); detErr == nil && len(dirs) > 0 {\n\t\t\t\treturn nil, fmt.Errorf(\"failed to start dolt server after %d attempts: %w\\n\"+\n\t\t\t\t\t\"Corrupt manifest with no recoverable data detected (GH#3290) in:\\n  %s\\n\"+\n\t\t\t\t\t\"Run 'bd doctor --fix' to back up the corrupt database(s) and reinitialize.\\nCheck logs: %s\",\n\t\t\t\t\tattempts, lastErr, strings.Join(dirs, \"\\n  \"), logPath(beadsDir))\n\t\t\t}\n\t\t\treturn nil, fmt.Errorf(\"failed to start dolt server after %d attempts: %w\\nCheck logs: %s\",\n\t\t\t\tattempts, lastErr, logPath(beadsDir))\n\t\t}\n\t}\n\n\t// Write PID and port files\n\tif err := os.WriteFile(pidPath(beadsDir), []byte(strconv.Itoa(pid)), 0600); err != nil {\n\t\tif proc, findErr := os.FindProcess(pid); findErr == nil {\n\t\t\t_ = proc.Kill()\n\t\t}\n\t\treturn nil, fmt.Errorf(\"writing PID file: %w\", err)\n\t}\n\tif err := writePortFile(beadsDir, actualPort); err != nil {\n\t\tif proc, findErr := os.FindProcess(pid); findErr == nil {\n\t\t\t_ = proc.Kill()\n\t\t}\n\t\t_ = os.Remove(pidPath(beadsDir))\n\t\treturn nil, fmt.Errorf(\"writing port file: %w\", err)\n\t}\n\n\t// Wait for server to accept connections\n\tif err := waitForReady(cfg.Host, actualPort, readyTimeout()); err != nil {\n\t\tif proc, findErr := os.FindProcess(pid); findErr == nil {\n\t\t\t_ = proc.Kill()\n\t\t}\n\t\t_ = os.Remove(pidPath(beadsDir))\n\t\t_ = os.Remove(portPath(beadsDir))\n\t\tif hasJournalCorruption, logErr := logHasCorruptJournalError(logPath(beadsDir)); logErr == nil && hasJournalCorruption {\n\t\t\treturn nil, fmt.Errorf(\"server started (PID %d) but not accepting connections on port %d: %w\\n\\n%s\",","sourceCodeStart":1467,"sourceCodeEnd":1503,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/doltserver/doltserver.go#L1467-L1503","documentation":"After a successful spawn, Start() persists the child's PID to pidPath(beadsDir). If that write fails, Start kills the freshly started process (to avoid an untracked orphan) and wraps the error as 'writing PID file'. The subsequent port-file write has the same kill-and-rollback behavior.","triggerScenarios":"os.WriteFile(pidPath(beadsDir), pid, 0600) fails right after a successful server launch — unwritable beads dir, disk full, or path collision.","commonSituations":"Beads dir permissions changed while the server was starting; disk filled during startup; another process recreated the beads dir as a read-only mount; security software blocking new files.","solutions":["Check and fix permissions on the beads data directory (chown/chmod) and restart.","Free disk space if the volume is full.","Remove any directory occupying the PID file's path.","Verify no sync/backup tool is flipping the directory read-only during startup."],"exampleFix":"// before\nls -ld ~/.beads  # owned by root\nbd start  # writing PID file: permission denied (server killed)\n// after\nsudo chown -R \"$USER\" ~/.beads\nbd start","handlingStrategy":"validation","validationCode":"await fs.mkdir(dataDir, { recursive: true });\nawait fs.access(dataDir, fs.constants.W_OK);\nconst pidPath = path.join(dataDir, 'dolt.pid');\ntry { const s = await fs.stat(pidPath); if (s.isDirectory()) throw new Error('pid path is a directory'); }\ncatch (e) { if (e.code !== 'ENOENT') throw e; }","typeGuard":"null","tryCatchPattern":"try {\n  await bdStart();\n} catch (e) {\n  if (/writing PID file/.test(e.message)) {\n    // server was killed to avoid an orphan; fix dir perms/space, then restart\n  }\n  throw e;\n}","preventionTips":["Keep the beads dir writable and disk non-full at all times.","Don't let external tools replace the beads dir during startup.","After uid changes, chown -R the beads dir.","Remove stray directories occupying pidfile paths."],"tags":["filesystem","pidfile","startup","cleanup"],"backgroundTag":"pidfile-write-failed","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}