{"record":{"id":"497e4eded2ef77ea","repo":"gastownhall/beads","slug":"quarantine-dead-backend-record-w","errorCode":null,"errorMessage":"quarantine dead backend record: %w","messagePattern":"quarantine dead backend record: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/dbproxy/proxy/endpoint.go","lineNumber":831,"sourceCode":"\t\t\tpf.Pid,\n\t\t\tfmt.Errorf(\"root identity mismatch (record has %q, workspace has %q)\", pf.RootID, expectedRootID),\n\t\t\tunverifiableProcessChecks{},\n\t\t)\n\t}\n\n\thandle, dead, err := openRecordedProcess(pf)\n\tif err != nil {\n\t\treturn unverifiableProcessError(\n\t\t\t\"backend cleanup\",\n\t\t\trecordPath,\n\t\t\tpf.Pid,\n\t\t\terr,\n\t\t\tunverifiableProcessChecks{},\n\t\t)\n\t}\n\tif dead {\n\t\tif _, err := quarantineRecord(rootDir, server.PIDFileName, time.Now()); err != nil {\n\t\t\treturn fmt.Errorf(\"quarantine dead backend record: %w\", err)\n\t\t}\n\t\treturn nil\n\t}\n\tif err := handle.Kill(); err != nil {\n\t\t_ = handle.Close()\n\t\treturn fmt.Errorf(\"kill verified orphan backend pid %d from %s: %w\", pf.Pid, recordPath, err)\n\t}\n\t// Close before waiting: an open handle on Windows keeps the dead PID\n\t// allocated, so procid.Verify would keep matching it and the exit wait\n\t// below would always time out.\n\tif err := handle.Close(); err != nil {\n\t\treturn fmt.Errorf(\"close verified backend process handle for pid %d: %w\", pf.Pid, err)\n\t}\n\tif err := waitForRecordedProcessExit(pf, backendExitTimeout); err != nil {\n\t\treturn fmt.Errorf(\"wait for verified orphan backend pid %d: %w\", pf.Pid, err)\n\t}\n\tif _, err := quarantineRecord(rootDir, server.PIDFileName, time.Now()); err != nil {\n\t\treturn fmt.Errorf(\"quarantine orphan backend record: %w\", err)","sourceCodeStart":813,"sourceCodeEnd":849,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/dbproxy/proxy/endpoint.go#L813-L849","documentation":"The recorded backend PID was opened and verified as belonging to this workspace, but the process is dead; cleanup quarantines the stale record. This error wraps a failure of that quarantine rename, so the dead record stays in place and cleanup aborts.","triggerScenarios":"openRecordedProcess(pf) reports dead=true and quarantineRecord(rootDir, server.PIDFileName, time.Now()) fails at internal/storage/dbproxy/proxy/endpoint.go:829-831 (rename/permission/IO error).","commonSituations":"Quarantine directory unwritable or on a full/read-only filesystem; the record file was locked or concurrently modified by another bd process; ownership changed (record created by another user).","solutions":["Fix permissions on the workspace/dbproxy directory so the rename can succeed.","Manually rename the record aside: mv <recordPath> <recordPath>.stale-$(date +%s) and retry.","Stop other concurrent bd processes that may be touching the record.","Address filesystem-level causes reported by the wrapped error (ENOSPC, EROFS)."],"exampleFix":"// before\nError: quarantine dead backend record: rename ...: file exists\n// after\n$ mv -f /ws/.beads/dbproxy/dolt-backend.pid /ws/.beads/dbproxy/dolt-backend.pid.stale-$(date +%s)\n$ bd doctor","handlingStrategy":"fallback","validationCode":"// Ensure quarantine is possible before cleanup:\nprobe := filepath.Join(rootDir, \".quarantine-probe\")\nif err := os.WriteFile(probe, nil, 0o644); err != nil {\n    return fmt.Errorf(\"workspace not writable, cleanup will fail: %w\", err)\n}\nos.Remove(probe)","typeGuard":null,"tryCatchPattern":"if err := cleanupOrphanBackend(rootDir); err != nil && strings.Contains(err.Error(), \"quarantine dead backend record\") {\n    os.Rename(recordPath, recordPath+\".stale-\"+strconv.FormatInt(time.Now().Unix(), 10))\n    err = cleanupOrphanBackend(rootDir)\n}","preventionTips":["Keep the workspace root writable and with free disk space.","Avoid concurrent bd processes on one workspace.","Remove expired .stale-* files regularly.","Watch for read-only container mounts."],"tags":["go","pidfile","quarantine","stale-record"],"backgroundTag":"quarantine-rename-failed","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}