gastownhall/beads · error
proxy.ForceStopUnverified: refusing to signal pid %d from %s
Error message
proxy.ForceStopUnverified: refusing to signal pid %d from %s: workspace scope could not be established (%v); stop the process manually, then quarantine the record by renaming %s to %s.stale-<unix-timestamp> before retrying
What it means
After confirming the executable is bd or dolt, ForceStopUnverified requires the process command line to reference the current workspace root before signaling. If the command line cannot be read or compared (the commandLineContains check errored), bd cannot prove the process belongs to this workspace and refuses to kill it, since a recycled PID running an unrelated bd/dolt could otherwise be terminated.
Source
Thrown at internal/storage/dbproxy/proxy/force_stop.go:230
return nil
}
executable = normalizeForceStopExecutable(executable)
report.Executable = executable
if executable != "bd" && executable != "dolt" {
return fmt.Errorf(
"proxy.ForceStopUnverified: refusing to signal pid %d from %s: executable basename is %q, want bd or dolt",
pid,
report.RecordPath,
executable,
)
}
// Basename alone would let a recycled PID now running an unrelated bd or
// dolt be killed; require the command line to tie the process to THIS
// workspace, and refuse when that scope cannot be established.
scoped, gone, err := proc.commandLineContains(rootDir)
if err != nil {
return fmt.Errorf(
"proxy.ForceStopUnverified: refusing to signal pid %d from %s: workspace scope could not be established (%v); stop the process manually, then quarantine the record by renaming %s to %s.stale-<unix-timestamp> before retrying",
pid,
report.RecordPath,
err,
report.RecordPath,
report.RecordPath,
)
}
if gone {
report.ProcessWasGone = true
return nil
}
if !scoped {
return fmt.Errorf(
"proxy.ForceStopUnverified: refusing to signal pid %d from %s: its command line does not reference workspace %s, so it may be an unrelated %s process; stop it manually if it is yours, then quarantine the record by renaming %s to %s.stale-<unix-timestamp> before retrying",
pid,
report.RecordPath,
rootDir,View on GitHub (pinned to 71377f2769)
Solutions
- Stop the process manually (kill <pid> as the owning user or inside its container)
- Quarantine the record: rename <record> to <record>.stale-<unix-timestamp>, then retry the force-stop
- Re-run inside the same user/session/container where the daemon runs so the cmdline is readable
- Check procfs availability and permissions (ls -l /proc/<pid>/cmdline) and adjust security policy if it blocks reads
Example fix
// before: retrying force-stop unchanged fails forever bd daemon --force-stop // after kill <pid> # stop manually as the owning user mv .bd/bd.pid .bd/bd.pid.stale-$(date +%s) bd daemon --force-stop # now succeeds or reports process gone
Defensive patterns
Strategy: try-catch
Validate before calling
// confirm cmdline of the pid is readable and references the workspace first
pid := readPidFromRecord(recordPath)
cmdline, err := os.ReadFile(fmt.Sprintf("/proc/%d/cmdline", pid))
if err != nil || !strings.Contains(strings.ReplaceAll(string(cmdline), "\x00", " "), rootDir) {
// cannot establish scope: stop manually and quarantine before calling
os.Rename(recordPath, recordPath+".stale-"+fmt.Sprint(time.Now().Unix()))
} Type guard
func isScopeUnestablishableErr(err error) bool {
return err != nil && strings.Contains(err.Error(), "workspace scope could not be established")
} Try / catch
err := proxy.ForceStopUnverified(ctx, rootDir, pidName, deadline)
if isScopeUnestablishableErr(err) {
// follow the remediation in the message: manual kill + quarantine, then retry
return fmt.Errorf("stop pid manually, rename %s to %s.stale-<ts>, retry", recordPath, recordPath)
} Prevention
- Launch daemons from within the workspace so the root path appears in argv
- Run force-stop from the same user/container/namespace as the daemon
- Keep procfs accessible (check SELinux/AppAudit policies in hardened environments)
- Quarantine rather than delete unreadable records
When it happens
Trigger: proxy.ForceStopUnverified when reading /proc/<pid>/cmdline (or platform equivalent) fails: permission denied on another user's process, cmdline unavailable in the container/namespace, procfs not mounted, or a transient kernel error while the process is exiting.
Common situations: bd/dolt daemon started under a different user or in a different container than the bd client attempting force-stop; hardened environments blocking cmdline reads; ephemeral runners where procfs access is restricted.
Related errors
- proxy.ForceStopUnverified: inspect executable for pid %d: %w
- proxy.ForceStopUnverified: publish stop epoch: %w
- proxy.ForceStopUnverified: probe %s: %w
- proxy.ForceStopUnverified: open pid %d: %w
- proxy.ForceStopUnverified: refusing to signal pid %d from %s
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/960445d343c6d68c.
Report an issue: GitHub.