gastownhall/beads · error

probe %s: %w

Error message

probe %s: %w

What it means

stopAndAcquire failed to even probe the lock file (util.TryLock on proxy.lock or dolt backend lock) with a non-'already locked' error. Since the state of the lock is unknown, Shutdown aborts rather than guessing. The wrapped error is the underlying OS-level failure.

Source

Thrown at internal/storage/dbproxy/proxy/shutdown.go:282

				return nil, fmt.Errorf("kill verified pid %d from %s: %w", pf.Pid, recordPath, killErr)
			}
			if closeErr := handle.Close(); closeErr != nil {
				lock.Unlock()
				return nil, fmt.Errorf("close verified process handle for pid %d: %w", pf.Pid, closeErr)
			}
			waitBudget := max(time.Until(deadline), shutdownPostKillMinimum)
			if waitErr := waitForRecordedProcessExit(pf, waitBudget); waitErr != nil {
				lock.Unlock()
				return nil, fmt.Errorf("confirm verified pid %d stopped: %w", pf.Pid, waitErr)
			}
			if removeErr := pidfile.Remove(rootDir, pidName); removeErr != nil {
				lock.Unlock()
				return nil, fmt.Errorf("remove stopped process record %s: %w", recordPath, removeErr)
			}
			return lock, nil

		case !lockfile.IsLocked(err):
			return nil, fmt.Errorf("probe %s: %w", lockPath, err)
		}

		pf, readErr := pidfile.Read(rootDir, pidName)
		if readErr != nil {
			if isMalformedPIDFileError(readErr) {
				return nil, unverifiableProcessError(
					"shutdown",
					recordPath,
					0,
					readErr,
					unverifiableProcessChecks{},
				)
			}
			return nil, fmt.Errorf("read held-lock record %s: %w", recordPath, readErr)
		}
		if pf != nil {
			if validateErr := validateKillRecord(rootDir, pf, wantKind, checks); validateErr != nil {
				dead, live, probeErr := classifyInvalidKillRecord(pf, validateErr)

View on GitHub (pinned to 71377f2769)

Solutions

  1. Run bd shutdown from the correct workspace root (the one containing .beads).
  2. Check the lock file and directory exist and are writable: ls -la .beads/*.lock.
  3. Inspect the wrapped %w error: ENOENT means wrong rootDir; EACCES means permissions; ENOLCK/EOPNOTSUPP means the filesystem doesn't support locks.
  4. Copy the workspace to a local filesystem if it lives on NFS/network storage.

Example fix

// before
err := proxy.Shutdown("/mnt/nfs/project") // probe ...lock: operation not supported
// after
err := proxy.Shutdown("/home/user/project") // local fs supporting flock
Defensive patterns

Strategy: validation

Validate before calling

fi

Try / catch

if err := proxy.Shutdown(rootDir); err != nil && strings.Contains(err.Error(), "probe ") {
    // inspect wrapped cause: wrong rootDir vs permissions vs unsupported fs
}

Prevention

When it happens

Trigger: util.TryLock returns an error that is neither success nor lockfile.IsLocked — e.g. the lock file's parent directory doesn't exist, permission denied on the lock file, or a filesystem-level flock error.

Common situations: Running shutdown outside the workspace (missing .beads dir), wrong rootDir passed to Shutdown, directory permissions broken after a copy/restore, or a corrupted/exotic filesystem that doesn't support flock (some network mounts).

Related errors


AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30). Data as JSON: /api/errors/c3fd1debcb04c5ad. Report an issue: GitHub.