gastownhall/beads · error

quarantine orphan backend record: %w

Error message

quarantine orphan backend record: %w

What it means

Final step of orphan backend cleanup: after the verified process was killed and confirmed exited, the stale PID record is quarantined (renamed into the quarantine area). This error wraps a failure of that final quarantineRecord call — the workspace is now backend-free but the stale record file remains, so cleanup reports failure.

Source

Thrown at internal/storage/dbproxy/proxy/endpoint.go:849

			return fmt.Errorf("quarantine dead backend record: %w", err)
		}
		return nil
	}
	if err := handle.Kill(); err != nil {
		_ = handle.Close()
		return fmt.Errorf("kill verified orphan backend pid %d from %s: %w", pf.Pid, recordPath, err)
	}
	// Close before waiting: an open handle on Windows keeps the dead PID
	// allocated, so procid.Verify would keep matching it and the exit wait
	// below would always time out.
	if err := handle.Close(); err != nil {
		return fmt.Errorf("close verified backend process handle for pid %d: %w", pf.Pid, err)
	}
	if err := waitForRecordedProcessExit(pf, backendExitTimeout); err != nil {
		return fmt.Errorf("wait for verified orphan backend pid %d: %w", pf.Pid, err)
	}
	if _, err := quarantineRecord(rootDir, server.PIDFileName, time.Now()); err != nil {
		return fmt.Errorf("quarantine orphan backend record: %w", err)
	}
	return nil
}

type unverifiableProcessChecks struct {
	LiveEstablished bool
	LegacyProxy     bool
}

func unverifiableProcessError(
	operation string,
	recordPath string,
	pid int,
	cause error,
	checks unverifiableProcessChecks,
) error {
	liveness := ""
	if checks.LiveEstablished {

View on GitHub (pinned to 71377f2769)

Solutions

  1. Fix permissions on the workspace and quarantine directory, then retry cleanup.
  2. Manually rename the record: mv <recordPath> <recordPath>.stale-$(date +%s) — the backend process is already gone at this point.
  3. Stop other concurrent bd instances that may be touching the record.
  4. Address wrapped filesystem causes (ENOSPC/EROFS) before retrying.

Example fix

// before
Error: quarantine orphan backend record: rename ...: permission denied
// after
$ mv /ws/.beads/dbproxy/dolt-backend.pid /ws/.beads/dbproxy/dolt-backend.pid.stale-$(date +%s)
$ bd doctor
Defensive patterns

Strategy: fallback

Validate before calling

// Verify the record is rename-able before cleanup:
if _, err := os.Stat(recordPath); err != nil {
    return nil // nothing to quarantine
}
if err := os.Chmod(recordPath, 0o644); err != nil {
    return fmt.Errorf("record not quarantine-able: %w", err)
}

Try / catch

if err := cleanupOrphanBackend(rootDir); err != nil && strings.Contains(err.Error(), "quarantine orphan backend record") {
    // backend already killed and confirmed exited; safe to rename manually
    os.Rename(recordPath, recordPath+".stale-"+strconv.FormatInt(time.Now().Unix(), 10))
}

Prevention

When it happens

Trigger: waitForRecordedProcessExit succeeded and quarantineRecord(rootDir, server.PIDFileName, time.Now()) fails at internal/storage/dbproxy/proxy/endpoint.go:848-849 (rename permission/IO error, target conflict).

Common situations: Quarantine directory not writable; filesystem full or read-only; another bd process recreated/locked the record between exit-wait and quarantine; ownership changed mid-cleanup.

Related errors


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