{"record":{"id":"0668ffd3e0a5edd6","repo":"gastownhall/beads","slug":"procid-process-birth-identity-is-not-implemented","errorCode":null,"errorMessage":"procid: process-birth identity is not implemented on %s","messagePattern":"procid: process-birth identity is not implemented on (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"info","filePath":"internal/procid/procid_unsupported.go","lineNumber":19,"sourceCode":"//go:build !linux && !darwin && !windows\n\npackage procid\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"runtime\"\n)\n\n// ErrUnsupported marks platforms with no process-birth identity\n// implementation (no /proc, no pidfd, no SysctlKinfoProc in x/sys). The\n// dbproxy machinery that needs birth identity refuses cleanly at startup\n// there instead of running with an unverifiable PID: reattach-and-signal\n// without birth identity is exactly the PID-reuse race this package exists\n// to close. Everything outside dbproxy is independent of procid, so ordinary\n// bd use on these platforms is unaffected — which matches what they had\n// before dbproxy existed (v1.1.2 shipped FreeBSD with no dbproxy at all).\nvar ErrUnsupported = fmt.Errorf(\"procid: process-birth identity is not implemented on %s\", runtime.GOOS)\n\n// Handle exists so cross-platform callers type-check; no instance can be\n// constructed because Open always fails.\ntype Handle struct{}\n\nfunc Capture(pid int) (Token, error) { return \"\", ErrUnsupported }\n\nfunc Verify(pid int, tok Token) (bool, error) { return false, ErrUnsupported }\n\nfunc Open(pid int, tok Token) (*Handle, error) { return nil, ErrUnsupported }\n\nfunc (h *Handle) Signal(sig os.Signal) error { return ErrUnsupported }\n\nfunc (h *Handle) Kill() error { return ErrUnsupported }\n\nfunc (h *Handle) Close() error { return nil }\n\n// IsProcessGone reports false: ErrUnsupported is a capability statement, not","sourceCodeStart":1,"sourceCodeEnd":37,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/procid/procid_unsupported.go#L1-L37","documentation":"ErrUnsupported is a sentinel error (public var) indicating that process-birth identity (PID + start-time tokens, the anti-PID-reuse mechanism) has no implementation on the current OS (runtime.GOOS is baked into the message). It is returned by Capture (and Open) on unsupported platforms so dbproxy-dependent callers refuse cleanly at startup instead of operating with an unverifiable PID. Ordinary bd usage outside dbproxy is unaffected by design.","triggerScenarios":"Calling procid.Capture, procid.Open, or any Handle-using API (e.g. inside dbproxy startup) on FreeBSD, OpenBSD, NetBSD, or any GOOS without a procid implementation file (only Linux and Windows have real implementations); building/running dbproxy-dependent machinery on such a platform.","commonSituations":"Deploying beads with dbproxy enabled to FreeBSD after v1.1.2 (which shipped FreeBSD with no dbproxy at all); cross-compiling and running on a BSD variant; CI matrix jobs on unsupported GOOS.","solutions":["If you do not need process-birth identity, keep usage outside dbproxy — ordinary bd commands work fine on these platforms","On FreeBSD and similar, either avoid enabling dbproxy machinery or run the dbproxy-dependent component on Linux/Windows instead","If you need support on a new platform, implement a procid_<goos>.go backend providing Capture/Verify with platform birth identity (e.g. kvm/proc credentials on BSDs)","Check errors.Is(err, procid.ErrUnsupported) at startup to fail fast with a clear message instead of a mid-run surprise"],"exampleFix":"// before\ntok, err := procid.Capture(pid)\nif err != nil {\n\treturn err // cryptic \"not implemented on freebsd\" mid-flight\n}\n// after\ntok, err := procid.Capture(pid)\nif errors.Is(err, procid.ErrUnsupported) {\n\treturn fmt.Errorf(\"dbproxy requires birth identity; unsupported on %s — run on linux/windows\", runtime.GOOS)\n}\nif err != nil {\n\treturn err\n}","handlingStrategy":"fallback","validationCode":"func birthIdentitySupported() bool {\n\tswitch runtime.GOOS {\n\tcase \"linux\", \"windows\":\n\t\treturn true\n\tdefault:\n\t\treturn false\n\t}\n}","typeGuard":"func isUnsupportedPlatform(err error) bool {\n\treturn errors.Is(err, procid.ErrUnsupported)\n}","tryCatchPattern":"tok, err := procid.Capture(pid)\nif errors.Is(err, procid.ErrUnsupported) {\n\t// degrade: skip identity verification or refuse dbproxy features\n\tlog.Warnf(\"no birth identity on %s; skipping PID-reuse protection\", runtime.GOOS)\n\treturn runWithoutIdentity(pid)\n}\nif err != nil {\n\treturn err\n}","preventionTips":["Gate dbproxy-dependent features on runtime.GOOS at startup (linux/windows only)","Detect ErrUnsupported once at init and disable the feature, not mid-operation","Do not fake a token on unsupported platforms — that defeats the PID-reuse protection","If FreeBSD support is needed, contribute a procid_freebsd.go backend rather than stubbing Capture"],"tags":["portability","unsupported-platform","freebsd","pid-reuse"],"backgroundTag":"platform-unsupported","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}