gastownhall/beads · error
proxy.ForceStopUnverified: record has a verifiable v2 worksp
Error message
proxy.ForceStopUnverified: record has a verifiable v2 workspace identity; use proxy.Shutdown
What it means
requireUnverifiableRecord refuses to force-stop a pidfile record whose RootID matches the current workspace. Such a record has a verifiable v2 workspace identity, meaning the safe proxy.Shutdown path should be used instead of the destructive force-stop path. ForceStopUnverified is deliberately restricted to records whose ownership cannot be verified.
Source
Thrown at internal/storage/dbproxy/proxy/force_stop.go:182
return nil, nil
}
report.RecordFound = true
report.PID = record.Pid
return record, nil
}
func requireUnverifiableRecord(rootDir string, record *pidfile.PidFile, wantKind string) error {
if err := record.ValidateV2(wantKind); err != nil {
return nil
}
rootID, err := identity.RootID(rootDir)
if err != nil {
// Failing open here would route a possibly-verifiable record into the
// destructive force path; surface the identity failure instead.
return fmt.Errorf("proxy.ForceStopUnverified: resolve workspace identity: %w", err)
}
if record.RootID == rootID {
return errors.New(
"proxy.ForceStopUnverified: record has a verifiable v2 workspace identity; use proxy.Shutdown",
)
}
return nil
}
func inspectAndStopUnverifiedPID(rootDir string, pid int, deadline time.Time, report *ForceStopReport) error {
if pid <= 0 {
return fmt.Errorf("proxy.ForceStopUnverified: record %s has invalid pid %d", report.RecordPath, pid)
}
// One stable handle covers inspection and signaling, so the PID cannot be
// recycled between the executable check and the kill on platforms with a
// pinning primitive (Linux pidfd, Windows process handle).
proc, gone, err := openUnverifiedProcess(pid)
if err != nil {
return fmt.Errorf("proxy.ForceStopUnverified: open pid %d: %w", pid, err)
}
if gone {View on GitHub (pinned to 71377f2769)
Solutions
- Call proxy.Shutdown instead of ForceStopUnverified for records with a verifiable identity
- Verify you are targeting the correct rootDir (the error means this workspace owns the record)
- If the record is truly stale, remove the identity mismatch or delete the pidfile manually after confirming the process
Example fix
// before _, err := proxy.ForceStopUnverified(root) // record owned by this workspace // after report, err := proxy.Shutdown(ctx, root) // safe, verified path
Defensive patterns
Strategy: try-catch
Validate before calling
if record.RootID == currentWorkspaceRootID() {
// record is verifiable — use Shutdown, not ForceStopUnverified
return proxy.Shutdown(ctx, root)
} Try / catch
if _, err := proxy.ForceStopUnverified(root); err != nil {
if strings.Contains(err.Error(), "verifiable v2 workspace identity") {
_, err = proxy.Shutdown(ctx, root)
}
return err
} Prevention
- Use ForceStopUnverified only for records from other/unknown workspaces
- Default to proxy.Shutdown for your own workspace's pidfile
- Compare record.RootID against the local rootID before choosing the force path
When it happens
Trigger: Calling proxy.ForceStopUnverified on a rootDir whose pidfile record was written by the current workspace (record.RootID == resolved rootID).
Common situations: Misunderstanding the API split: using ForceStopUnverified for normal restarts instead of Shutdown; workspace identity files regenerated or moved so RootID unexpectedly matches.
Related errors
- proxy.ForceStopUnverified: at most one options value is allo
- expected relative path, got absolute: %s
- proxy.ForceStopUnverified: confirm pid %d exit: %w
- proxy.ForceStopUnverified: timeout waiting for pid %d to exi
- proxy.ForceStopUnverified: acquire %s: %w
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/ec25e56215f15059.
Report an issue: GitHub.