gastownhall/beads · warning
reading another process's command line is not supported on w
Error message
reading another process's command line is not supported on windows
What it means
On Windows, the unverifiedProcess implementation cannot read another process's command line, so commandLineContains always fails with this error. Force-stop therefore refuses to verify workspace scoping via command line on Windows and will not signal the process, per the 'refuse rather than guess' policy.
Source
Thrown at internal/storage/dbproxy/proxy/unverified_process_windows.go:69
func (p *unverifiedProcess) executableBasename() (basename string, gone bool, err error) {
buffer := make([]uint16, 32768)
size := uint32(len(buffer))
if err := windows.QueryFullProcessImageName(p.handle, 0, &buffer[0], &size); err != nil {
return "", false, fmt.Errorf("query image name for pid %d: %w", p.pid, err)
}
return filepath.Base(syscall.UTF16ToString(buffer[:size])), false, nil
}
// commandLineContains cannot establish workspace scope on Windows: another
// process's command line is only reachable through undocumented PEB reads,
// so force-stop refuses rather than signaling on basename alone.
func (p *unverifiedProcess) commandLineContains(string) (matched bool, gone bool, err error) {
exited, exitErr := handleExited(p.handle)
if exitErr == nil && exited {
return false, true, nil
}
return false, false, errors.New("reading another process's command line is not supported on windows")
}
// kill terminates the process through the held handle. gone reports a target
// that had already exited.
func (p *unverifiedProcess) kill() (gone bool, err error) {
if err := windows.TerminateProcess(p.handle, 1); err != nil {
if exited, exitErr := handleExited(p.handle); exitErr == nil && exited {
return true, nil
}
return false, fmt.Errorf("terminate pid %d: %w", p.pid, err)
}
return false, nil
}
func (p *unverifiedProcess) exited() (bool, error) {
return handleExited(p.handle)
}
View on GitHub (pinned to 71377f2769)
Solutions
- On Windows, stop the process manually (Task Manager / taskkill) after visually confirming it belongs to this workspace
- Delete the stale pidfile once the process is confirmed dead
- Handle this error in tooling by falling back to manual cleanup instead of retrying
Example fix
// before
matched, gone, err := proc.commandLineContains(ws)
// after
matched, gone, err := proc.commandLineContains(ws)
if err != nil && runtime.GOOS == "windows" {
return fmt.Errorf("manual verification required: %w", err)
} Defensive patterns
Strategy: fallback
Validate before calling
if runtime.GOOS == "windows" {
// command-line verification unsupported; plan manual cleanup
return manualForceStopGuidance(record)
} Try / catch
matched, gone, err := proc.commandLineContains(ws)
if err != nil {
if runtime.GOOS == "windows" {
return fmt.Errorf("verify manually (tasklist/taskkill): %w", err)
}
return err
} Prevention
- Don't rely on command-line inspection in cross-platform kill paths
- On Windows, verify workspace scope via other means (pidfile pairing) before killing
- Document manual taskkill steps for Windows users hitting force-stop refusals
When it happens
Trigger: Calling ForceStopUnverified on Windows where matching requires inspecting a foreign process's command line (e.g. verifying the process belongs to this workspace).
Common situations: Running beads force-stop on Windows with legacy/paired records whose basename alone (bd/dolt) is insufficient to establish workspace scope.
Related errors
- close verified backend process handle for pid %d: %w
- open process %d: %w
- no store is open for this workspace
- not found
- no absolute native user directory is available
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/df57cfbc14c6d40f.
Report an issue: GitHub.