{"record":{"id":"43dd1af3faf132b5","repo":"gastownhall/beads","slug":"probe-recorded-pid-w","errorCode":null,"errorMessage":"probe recorded pid: %w","messagePattern":"probe recorded pid: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/dbproxy/proxy/endpoint.go","lineNumber":793,"sourceCode":"\t\t\t\treadErr,\n\t\t\t\tunverifiableProcessChecks{},\n\t\t\t)\n\t\t}\n\t\treturn fmt.Errorf(\"read backend record %s: %w\", recordPath, readErr)\n\t}\n\tif pf == nil {\n\t\treturn nil\n\t}\n\tif err := pf.ValidateV2(pidfile.KindDoltBackend); err != nil {\n\t\tdead, live, probeErr := probeUnverifiablePID(pf.Pid)\n\t\tif dead {\n\t\t\tif _, quarantineErr := quarantineRecord(rootDir, server.PIDFileName, time.Now()); quarantineErr != nil {\n\t\t\t\treturn fmt.Errorf(\"quarantine dead unverifiable backend record: %w\", quarantineErr)\n\t\t\t}\n\t\t\treturn nil\n\t\t}\n\t\tif probeErr != nil {\n\t\t\terr = errors.Join(err, fmt.Errorf(\"probe recorded pid: %w\", probeErr))\n\t\t}\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\t\tLiveEstablished: live,\n\t\t\t},\n\t\t)\n\t}\n\texpectedRootID, err := identity.RootID(rootDir)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"resolve backend root identity: %w\", err)\n\t}\n\tif pf.RootID != expectedRootID {\n\t\treturn unverifiableProcessError(\n\t\t\t\"backend cleanup\",","sourceCodeStart":775,"sourceCodeEnd":811,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/dbproxy/proxy/endpoint.go#L775-L811","documentation":"When a backend PID record fails V2 validation, cleanup probes the recorded PID to see if the process is dead or alive. If that probe itself errors (and the PID was not confirmed dead), the probe error is joined with the validation error and surfaced inside an unverifiableProcessError, refusing cleanup because liveness could not be established.","triggerScenarios":"pf.ValidateV2(pidfile.KindDoltBackend) fails AND probeUnverifiablePID(pf.Pid) returns a non-nil error (e.g. pid <= 0 'record has no valid pid', or the OS process-liveness check fails) at internal/storage/dbproxy/proxy/endpoint.go:785-793.","commonSituations":"A corrupt or hand-edited pidfile with pid 0/negative; an OS API failure while probing (e.g. OpenProcess failure on Windows not implying death); a record written by a very old bd version with an incompatible format.","solutions":["Inspect the record file; fix or remove an invalid pid value (pid must be > 0).","Follow the unverifiableProcessError guidance: stop the recorded process with the binary that started it, then quarantine manually: mv <recordPath> <recordPath>.stale-<unix-ts>.","Recreate the workspace metadata if the record is from an incompatible legacy version.","Retry after confirming no dolt-backend process for this workspace is running."],"exampleFix":"// before (record with pid 0)\nError: backend cleanup refused for unverifiable process pid 0 ...: probe recorded pid: record has no valid pid\n// after\n$ cat /ws/.beads/dbproxy/dolt-backend.pid  # inspect\n$ mv /ws/.beads/dbproxy/dolt-backend.pid /ws/.beads/dbproxy/dolt-backend.pid.stale-$(date +%s)","handlingStrategy":"try-catch","validationCode":"// Before cleanup, sanity-check the record's pid yourself:\nif data, err := os.ReadFile(recordPath); err == nil {\n    var rec struct{ Pid int `json:\"pid\"` }\n    if json.Unmarshal(data, &rec) == nil && rec.Pid <= 0 {\n        os.Rename(recordPath, recordPath+\".stale-\"+fmt.Sprint(time.Now().Unix()))\n    }\n}","typeGuard":"func hasValidPID(pf *pidfile.Pidfile) bool { return pf != nil && pf.Pid > 0 }","tryCatchPattern":"var ule *unverifiableLifecycleError\nif err := cleanupOrphanBackend(rootDir); err != nil {\n    if errors.As(err, &ule) {\n        // follow guidance: stop recorded process, then mv record to .stale-<ts>\n        return nil\n    }\n    return err\n}","preventionTips":["Never edit pidfile records by hand.","Upgrade bd fully before inspecting records from old versions.","Confirm the dolt-backend process state with ps/tasklist before manual quarantine.","Keep one bd process per workspace to avoid racing liveness probes."],"tags":["go","pidfile","process-liveness","probe"],"backgroundTag":"process-liveness-probe-failed","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}