gastownhall/beads · error
resolve proxy root identity: %w
Error message
resolve proxy root identity: %w
What it means
Wraps a failure of identity.RootID(p.rootDir), which resolves the stable root identity of the database directory used in the proxy's IdentReply. If the root identity file/record cannot be read or is invalid, the backend is stopped and startup aborts - the proxy refuses to advertise itself without a verifiable root identity.
Source
Thrown at internal/storage/dbproxy/proxy/server.go:288
if err := waitForServerReady(ctx, p.server, serverReadyTimeout); err != nil {
if changed, cerr := stopEpochChanged(p.rootDir, p.stopEpoch); cerr == nil && changed {
return abortInterruptedStart()
}
p.stats.IncBackendStop()
_ = stopBackendBounded(p.server)
return fmt.Errorf("database server not ready: %w", err)
}
birth, err := procid.Capture(os.Getpid())
if err != nil {
p.stats.IncBackendStop()
_ = stopBackendBounded(p.server)
return fmt.Errorf("capture proxy birth identity: %w", err)
}
rootID, err := identity.RootID(p.rootDir)
if err != nil {
p.stats.IncBackendStop()
_ = stopBackendBounded(p.server)
return fmt.Errorf("resolve proxy root identity: %w", err)
}
upstreamID := p.server.ID(ctx)
identMu.Lock()
identReply.RootID = rootID
identReply.UpstreamID = upstreamID
identReply.PID = os.Getpid()
identReply.Birth = string(birth)
identReply.ControlPort = control.Port()
identMu.Unlock()
// Last fence before publishing: the spawn marker was cleared when this
// process took proxy.lock, so a `bd dolt stop` that began during a slow
// backend start has no record of this attempt. It did advance the stop
// epoch first, so re-check it here and abort instead of publishing a
// running proxy after that stop returned. The startup epoch watcher is
// stopped (synchronously) first: past this fence a stop finds the
// published proxy.pid and stops the proxy through it, so a watcher
// cancellation must not race the publish.View on GitHub (pinned to 71377f2769)
Solutions
- Re-initialize or repair the database root (re-run init) so a valid root identity exists
- Restore the missing identity files from a known-good backup of rootDir
- Check file permissions on the identity metadata files in rootDir
- Confirm the tooling and proxy versions agree on the identity schema
Example fix
// before // identity file missing after manual dir copy $ cp -r /data/db /data/db-copy # dropped hidden identity files // after $ bd init /data/db-copy # or restore the full directory including identity metadata
Defensive patterns
Strategy: validation
Validate before calling
// Confirm the root identity metadata exists before start
if _, err := os.Stat(filepath.Join(rootDir, ".beads_root_id")); os.IsNotExist(err) {
return fmt.Errorf("root identity missing in %s; re-init the database", rootDir)
} Try / catch
if err := p.ListenAndServe(ctx); err != nil {
if strings.Contains(err.Error(), "resolve proxy root identity") {
log.Fatalf("rootDir identity unreadable/incompatible: %v - re-run init", err)
}
log.Fatal(err)
} Prevention
- Copy database directories with all hidden identity files (cp -a, tar)
- Run init after restoring from backup to regenerate metadata
- Keep proxy and CLI tool versions in lockstep to avoid schema drift
When it happens
Trigger: ListenAndServe -> identity.RootID fails because the root metadata in rootDir is missing, corrupted, was written by an incompatible schema version, or is unreadable due to permissions.
Common situations: rootDir initialized by an older/newer beads version (schema drift); partially initialized directory where init was interrupted; manual copy of the database dir that dropped identity files; permission changes after backup/restore.
Related errors
- metadata validation failed for issue %s: %w
- metadata schema violation: %s
- uow: database %q has no project identity (metadata._project_
- ExternalDoltConfig: must set Socket or (Host, Port)
- identity: request refused
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/a33f0f3e7e2ddf9f.
Report an issue: GitHub.