gastownhall/beads · error
probe proxy lock: %w
Error message
probe proxy lock: %w
What it means
This is not a lock-contention issue: util.TryLock failed with an error that is NOT 'lock already held' (lockfile.IsLocked(err) is false). That means the lock file itself could not be probed/created — an I/O or environmental failure — so the library cannot safely proceed and wraps the underlying error. Treat it as a filesystem problem, not a busy proxy.
Source
Thrown at internal/storage/dbproxy/proxy/endpoint.go:271
}
if markerActive {
lock.Unlock()
lastSpawnErr = nil
// This break exits the switch only; the outer discovery loop
// continues with its normal bounded poll.
break
}
var ep Endpoint
ep, lastSpawnErr = spawnAndHandoff(rootDir, opts, deadline, stopEpoch, lock, discovery)
if lastSpawnErr == nil {
return ep, nil
}
if errors.Is(lastSpawnErr, errStartInterrupted) {
return Endpoint{}, lastSpawnErr
}
case !lockfile.IsLocked(err):
return Endpoint{}, fmt.Errorf("probe proxy lock: %w", err)
case discovery.status == adoptionLegacy:
recordPath := pidfile.Path(rootDir, PIDFileName)
return Endpoint{}, fmt.Errorf(
"legacy proxy record %s is protected by held lock %s; stop the pre-upgrade proxy with the old bd binary or wait for its idle exit, then quarantine the record manually by renaming %s to %s.stale-<unix-timestamp> before retrying",
recordPath,
filepath.Join(rootDir, LockFileName),
recordPath,
recordPath,
)
}
select {
case <-timeout.C:
if lastSpawnErr != nil {
return Endpoint{}, lastSpawnErr
}
return Endpoint{}, fmt.Errorf("timeout waiting for proxy on %s", rootDir)
case <-poll.C:View on GitHub (pinned to 71377f2769)
Solutions
- Verify <rootDir> exists and is writable; recreate the directory if it was removed
- Check the mount is not read-only (mount | grep, or try touching a file in rootDir)
- If a stale proxy.lock file exists but is not actually locked, remove it and retry
- Re-run as a user with write access to the workspace
Example fix
// before error: probe proxy lock: open /repo/.beads/proxy.lock: no such file or directory // after $ mkdir -p /repo/.beads && touch /repo/.beads/.write-test && rm /repo/.beads/.write-test $ bd ready
Defensive patterns
Strategy: try-catch
Validate before calling
// Ensure the workspace is writable before attempting proxy open
probe := filepath.Join(rootDir, ".write-probe")
if err := os.WriteFile(probe, nil, 0o600); err != nil {
return fmt.Errorf("workspace not writable: %w", err)
}
os.Remove(probe) Try / catch
err := proxy.GetCreateDatabaseProxyServerEndpoint(root, opts)
var lockErr *fs.PathError
if err != nil && strings.HasPrefix(err.Error(), "probe proxy lock:") && errors.As(err, &lockErr) {
// filesystem-level lock failure: fix permissions/mount, do NOT busy-retry
return fmt.Errorf("fix workspace fs: %w", err)
} Prevention
- Health-check workspace writability at job start
- Do not delete the workspace directory while bd processes are alive
- Watch for noexec/read-only mount changes after CI cache restores
When it happens
Trigger: util.TryLock on <rootDir>/proxy.lock returns a non-IsLocked error: the lock file cannot be opened/created because the directory is missing or read-only, the OS lock syscall fails, or the lock path is invalid.
Common situations: Workspace directory deleted or renamed while bd was running; read-only mounts (CI cache restores, WSL cross-filesystem mounts); TMPDIR/overlay filesystem restrictions; running two tools with incompatible lock semantics on the same path.
Related errors
- discover proxy from %s: %w
- discover proxy from %s under lock: %w
- failed to read backup state: %w
- failed to write temp file: %w
- failed to sync temp file: %w
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/17b1f05c06f58302.
Report an issue: GitHub.