gastownhall/beads · error
reading gate %s: %w
Error message
reading gate %s: %w
What it means
Wraps an unexpected error from GetIssue while reading the gate inside the AddWaiter transaction. Unlike 'gate not found', this means the lookup itself failed — a storage/backend error, not a missing issue. The original error is preserved via %w for diagnosis.
Source
Thrown at cmd/bd/gate_proxied_server.go:253
}
}()
gateID := args[0]
waiter := args[1]
if uowProvider == nil {
return HandleError("proxied-server UOW provider not initialized")
}
applied, err := uow.RunTxResult(ctx, uowProvider, func(ctx context.Context, uw uow.UnitOfWork) (gateAddWaiterApply, string, error) {
var out gateAddWaiterApply
issue, err := uw.IssueUseCase().GetIssue(ctx, gateID)
if gateProxiedNotFound(err) {
return out, "", fmt.Errorf("gate not found: %s", gateID)
}
if err != nil {
return out, "", fmt.Errorf("reading gate %s: %w", gateID, err)
}
if issue.IssueType != "gate" {
return out, "", fmt.Errorf("%s is not a gate issue (type=%s)", gateID, issue.IssueType)
}
for _, w := range issue.Waiters {
if w == waiter {
out.already = true
// Empty commit message: a registered waiter is a no-op, and a
// no-op writes no Dolt commit.
return out, "", nil
}
}
newWaiters := append(issue.Waiters, waiter)
if err := uw.IssueUseCase().UpdateIssue(ctx, gateID, map[string]any{"waiters": newWaiters}, actor); err != nil {
return out, "", fmt.Errorf("updating gate: %w", err)
}View on GitHub (pinned to 71377f2769)
Solutions
- Check the wrapped cause (%w) to identify the storage failure
- Run `bd doctor` to validate database connectivity and health
- Retry the AddWaiter call — many driver/connection errors are transient
- If errors persist, inspect Dolt server logs and database state before further writes
Example fix
// before: no retry around the gate read
issue, err := uw.IssueUseCase().GetIssue(ctx, gateID)
if gateProxiedNotFound(err) { return out, "", fmt.Errorf("gate not found: %s", gateID) }
if err != nil { return out, "", fmt.Errorf("reading gate %s: %w", gateID, err) }
// after: caller retries transient read failures with backoff
var issue *Issue
backoff := 100 * time.Millisecond
for i := 0; i < 3; i++ {
issue, err = client.Show(ctx, gateID)
if err == nil { break }
if isNotFound(err) { return err }
time.Sleep(backoff); backoff *= 2
}
if err != nil { return fmt.Errorf("reading gate %s after retries: %w", gateID, err) } Defensive patterns
Strategy: retry
Validate before calling
ctx, cancel := context.WithTimeout(ctx, 10*time.Second) defer cancel() _ = bdClient.Show(ctx, "bd-probe") // probe read: if this fails, storage is unhealthy
Type guard
func isTransientStorageErr(err error) bool {
msg := err.Error()
return strings.Contains(msg, "connection") || strings.Contains(msg, "timeout") || strings.Contains(msg, "deadline")
} Try / catch
var issue *Issue
err := retry.Do(3, 200*time.Millisecond, func() error {
var e error
issue, e = client.Show(ctx, gateID)
if e != nil && isTransientStorageErr(e) { return e }
return retry.Stop(e)
})
if err != nil { return fmt.Errorf("reading gate %s: %w", gateID, err) } Prevention
- Ensure the Dolt server/storage backend is reachable before gate operations (bd doctor)
- Set explicit context timeouts so reads fail fast with a clear cause
- Retry transient connection errors with backoff before giving up
- Watch for lock contention from concurrent bd writers during transactions
When it happens
Trigger: IssueUseCase().GetIssue(ctx, gateID) returns an error that is not classified as not-found (gateProxiedNotFound is false) — e.g. Dolt connection failure, transaction abort, corrupt record, or context cancellation during the read.
Common situations: Dolt server down or network partition between bd and storage; context deadline exceeded while the transaction waits on a lock; database corruption or failed migration; transient driver errors under concurrent writes.
Related errors
- affected by batched wisp delete: %w
- resolve existing wisps for batch delete: %w
- ErrTransaction
- ErrExec
- database not available: %w
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/6d53594dd24829f8.
Report an issue: GitHub.