gastownhall/beads · error
proxied-server UOW provider not initialized
Error message
proxied-server UOW provider not initialized
What it means
bd's proxied-server import path requires a unit-of-work (UOW) provider that is created during command startup when running against a proxied server. runImportRecordsProxied checks `uowProvider == nil` before touching it; if the provider was never constructed, the import aborts rather than silently proceeding without a transactional backend. This is an internal initialization invariant, not a user-data problem.
Source
Thrown at cmd/bd/import_proxied_server.go:50
// parsed records. It mirrors runImportRecordsClassic stage for stage — dedup,
// dry-run classification, stale pre-filter, batch write, issue_prefix
// reconciliation — through the SAME classification and reporting code, with
// two deliberate structural differences:
//
// - ONE COMMIT PER INVOCATION. The classic path chunks a large import into
// bounded transactions (a SQLite write-lock fairness measure) and commits
// the issue_prefix sync separately; the proxied path has no PostRun
// auto-commit and the whole import — rows, memories, prefix sync — lands
// in ONE unit of work with ONE history entry, the Importer capability's
// contract.
//
// - The stale guard keeps its classic two-half shape: the pre-filter runs in
// its own read (reporting StaleSkippedIDs and keeping stale rows' aux data
// out of the batch), and RejectStaleUpserts re-checks updated_at inside
// the write transaction, closing the same race the classic path closes.
func runImportRecordsProxied(ctx context.Context, issues []*types.Issue, memories []memoryRecord, source string) error {
if uowProvider == nil {
return fmt.Errorf("proxied-server UOW provider not initialized")
}
// Dedup: skip issues whose title matches an existing open issue.
dedupHits := 0
if importDedup && len(issues) > 0 {
type dedupOutcome struct {
kept []*types.Issue
hits int
}
out, err := uow.RunTxRead(ctx, uowProvider, func(ctx context.Context, uw uow.UnitOfWork) (dedupOutcome, error) {
kept, hits := filterDuplicatesByTitle(ctx, uowImportTitleSearcher{uw: uw}, issues)
return dedupOutcome{kept: kept, hits: hits}, nil
})
if err != nil {
return err
}
issues = out.kept
dedupHits = out.hitsView on GitHub (pinned to 71377f2769)
Solutions
- Verify the proxied-server daemon is running and `bd` can connect (check `bd doctor` / daemon logs) so startup provider initialization completes.
- Re-run the command; transient bootstrap failures are resolved by a fresh invocation.
- If embedding/invoking programmatically, ensure the storage/UOW provider is initialized before calling import, mirroring the standard command startup.
- Check for version skew between bd client and proxied server and upgrade to matching versions.
Example fix
// before (embedded/harness use)
runImportRecordsProxied(ctx, issues, memories, source) // uowProvider still nil
// after
uowProvider = initUOWProvider(cfg) // run normal startup initialization first
if err := runImportRecordsProxied(ctx, issues, memories, source); err != nil { ... } Defensive patterns
Strategy: validation
Validate before calling
if uowProvider == nil {
return errors.New("storage provider not initialized: run provider bootstrap before import")
} Type guard
func providerReady(p uow.Provider) bool { return p != nil }
if _, ok := uowProvider.(uow.ImporterSource); !ok {
return errors.New("provider does not offer import surface")
} Prevention
- Always initialize the storage/UOW provider at command startup before any subcommand runs.
- Use `bd doctor` to verify the daemon/provider is healthy before scripted imports.
- When embedding, mirror the standard command bootstrap instead of calling import functions directly.
- Keep client and proxied-server versions aligned.
When it happens
Trigger: Running `bd import` through the proxied-server path where the daemon/provider bootstrap failed, was skipped, or the command was invoked through a code path (or embedder) that never called the provider setup before reaching runImportRecordsProxied.
Common situations: The proxied daemon is not running or the proxy handshake failed so provider setup bailed early; an embedder or custom harness invokes the import function directly without initializing uowProvider; a version mismatch where the import path was refactored but the initialization step wasn't wired in.
Related errors
- no database connection
- graph create: %w
- resolving %s: %w
- no database connection
- no store is open for this workspace
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/96e33186a383ed5c.
Report an issue: GitHub.