gastownhall/beads · error
proxy.Shutdown: publish stop epoch: %w
Error message
proxy.Shutdown: publish stop epoch: %w
What it means
proxy.Shutdown begins by advancing the stop epoch so any in-flight start attempt aborts instead of republishing after the stop returns. If advanceStopEpoch fails — typically an I/O error writing the stop-epoch control file in rootDir — Shutdown returns immediately with the 'proxy.Shutdown: publish stop epoch: %w' prefix and never attempts to stop the proxy or backend.
Source
Thrown at internal/storage/dbproxy/proxy/shutdown.go:86
}
proxyRecoverable := shutdownErr.proxyErr == nil ||
errors.Is(shutdownErr.proxyErr, ErrUnverifiableProcess)
backendRecoverable := shutdownErr.backendErr == nil ||
errors.Is(shutdownErr.backendErr, ErrUnverifiableProcess)
return proxyRecoverable && backendRecoverable
}
// Shutdown stops the verified proxy and backend processes for rootDir.
//
// Advancing the stop epoch first makes every start attempt which began before
// this call terminally abort instead of retrying after its child is stopped.
// The proxy spawn marker covers the smaller release-lock-before-exec window:
// Shutdown waits for that marked attempt to either acquire proxy.lock or fail,
// then verifies and stops whatever it published. All waits are bounded by
// shutdownConfirmDeadline.
func Shutdown(rootDir string) error {
if err := advanceStopEpoch(rootDir); err != nil {
return fmt.Errorf("proxy.Shutdown: publish stop epoch: %w", err)
}
proxyLock, proxyErr := stopAndAcquire(
rootDir,
LockFileName,
PIDFileName,
pidfile.KindProxy,
killRecordChecks{
VerifyRoot: true,
CheckSpawnMarker: true,
},
)
if proxyLock != nil {
defer proxyLock.Unlock()
}
backendLock, backendErr := stopAndAcquire(
rootDir,View on GitHub (pinned to 71377f2769)
Solutions
- Verify rootDir is writable by the current user and has free space (touch <rootDir>/.wtest; df -h <rootDir>).
- Fix permissions/ownership on the workspace directory.
- Inspect the wrapped cause after the prefix for the exact syscall error and address it.
- Once writable, re-run the shutdown; the epoch will publish and stopping can proceed.
- If rootDir moved, run the shutdown from the correct workspace path.
Example fix
// before (shell) bd dolt stop # proxy.Shutdown: publish stop epoch: open .../stop-epoch: permission denied // after sudo chown -R "$USER" .beads # or move to a writable workspace bd dolt stop
Defensive patterns
Strategy: validation
Validate before calling
info, err := os.Stat(rootDir)
if err != nil {
return fmt.Errorf("workspace rootDir missing: %w", err)
}
if f, err := os.OpenFile(filepath.Join(rootDir, ".wtest"), os.O_CREATE|os.O_WRONLY, 0o644); err != nil {
return fmt.Errorf("cannot write stop-epoch in %s: %w", rootDir, err)
} else {
f.Close(); os.Remove(filepath.Join(rootDir, ".wtest"))
} Try / catch
if err := proxy.Shutdown(rootDir); err != nil {
if strings.Contains(err.Error(), "publish stop epoch") {
// fix writability/space of rootDir, then retry Shutdown
}
return err
} Prevention
- Run stop from the same user/workspace that started the proxy
- Ensure the workspace filesystem is mounted rw with free space
- Do not move or rename rootDir while a proxy lifecycle is in flight
- Check the wrapped syscall error under the prefix for the precise cause
When it happens
Trigger: Calling proxy.Shutdown (or bd dolt stop) when the stop-epoch file in rootDir cannot be written: read-only rootDir, disk full, permission denied, rootDir missing, or the epoch file path is otherwise unwritable.
Common situations: Workspace on a read-only or full filesystem; running as a different user than the process that started the proxy; rootDir moved/renamed between start and stop; SELinux/AppArmor denying writes.
Related errors
- server: DoltServer.Stop: remove pidfile: %w
- dolt path is not executable
- server: NewDoltServer: failed to determine absolute path of
- server: NewDoltServer: failed to determine absolute path of
- server: NewDoltServer: failed to determine absolute path of
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/3dee8f1f5535d18d.
Report an issue: GitHub.