{"record":{"id":"0d89984495e1b7dd","repo":"gastownhall/beads","slug":"empty-executable-basename-for-pid-d-0d8998","errorCode":null,"errorMessage":"empty executable basename for pid %d","messagePattern":"empty executable basename for pid (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/dbproxy/proxy/process_executable_linux.go","lineNumber":24,"sourceCode":"\t\"errors\"\n\t\"fmt\"\n\t\"io/fs\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"strconv\"\n)\n\nfunc processExecutableBasename(pid int) (basename string, gone bool, err error) {\n\ttarget, err := os.Readlink(\"/proc/\" + strconv.Itoa(pid) + \"/exe\")\n\tif err != nil {\n\t\tif errors.Is(err, fs.ErrNotExist) {\n\t\t\treturn \"\", true, nil\n\t\t}\n\t\treturn \"\", false, err\n\t}\n\tbase := filepath.Base(target)\n\tif base == \".\" || base == string(filepath.Separator) || base == \"\" {\n\t\treturn \"\", false, fmt.Errorf(\"empty executable basename for pid %d\", pid)\n\t}\n\treturn base, false, nil\n}\n","sourceCodeStart":6,"sourceCodeEnd":28,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/dbproxy/proxy/process_executable_linux.go#L6-L28","documentation":"On Linux, processExecutableBasename reads the /proc/<pid>/exe symlink target and returns its basename. If the target's basename is '.', the path separator, or empty, it cannot identify the executable, so this error is returned instead of a false verification match.","triggerScenarios":"Reading /proc/<pid>/exe for a pid whose link target is empty or degenerate — usually the process exited and /proc entry is being torn down, or permission to read the link failed leaving an empty result.","commonSituations":"Race with process exit during force-stop verification; containerized environments where /proc/<pid>/exe is restricted; pid reuse mid-check.","solutions":["Retry the lookup shortly after; transient /proc state usually resolves","Confirm the process is still alive before verification","Handle the error as 'cannot verify' and treat the stop as unverified rather than fatal"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"if _, err := os.Stat(fmt.Sprintf(\"/proc/%d\", pid)); err != nil { /* pid gone */ }","typeGuard":"func validBasename(b string) bool { return b != \"\" && b != \".\" && b != \"/\" }","tryCatchPattern":"base, exited, err := processExecutableBasename(pid)\nif err != nil { /* re-check /proc/<pid> and retry once */ }","preventionTips":["Expect /proc races when processes are exiting","Verify /proc/<pid>/exe is readable in your container/security context","Treat as 'unverified' rather than aborting the whole stop"],"tags":["process","linux","procfs"],"backgroundTag":"empty-executable-basename","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}