gastownhall/beads · error
uow: database %q has no project identity (metadata._project_
Error message
uow: database %q has no project identity (metadata._project_id) — the schema is managed by beads-team-server; ask your operator to provision it with 'bts init' (or heal an older bts database with 'bts migrate')
What it means
checkTeamServerIdentity refuses to connect when the database has no stored project identity (metadata._project_id is absent or empty). Unlike the legacy path, an empty identity is treated as an invalid state for a team-server database: soft-skipping would silently disable the project-mismatch guard for every client sharing the database.
Source
Thrown at internal/storage/uow/team_server_schema.go:77
if expectedProjectID == "" {
return nil
}
// A read error is surfaced rather than skipped: checkTeamServerSchema has
// already proven the beads schema is present at this binary's version, so
// the metadata table exists and a failure here is a real fault, not the
// legacy-database case verifyProjectIdentity tolerates.
dbProjectID, err := issueops.GetMetadataInTx(ctx, conn, "_project_id")
if err != nil {
return fmt.Errorf("uow: team-server identity check on database %q: %w", database, err)
}
// Unlike verifyProjectIdentity, an absent stored identity is NOT tolerated
// here. adoptTeamServerIdentity refuses to attach to a bts database that
// has no metadata._project_id at all, so for a team-server database this
// is an already-invalid state rather than a legacy one — and soft-skipping
// it would mean deleting one row from the shared database silently
// disables this guard for every client.
if dbProjectID == "" {
return fmt.Errorf(
"uow: database %q has no project identity (metadata._project_id) — the schema is managed by beads-team-server; ask your operator to provision it with 'bts init' (or heal an older bts database with 'bts migrate')",
database)
}
if dbProjectID != expectedProjectID {
return fmt.Errorf(
"PROJECT IDENTITY MISMATCH — refusing to connect\n\n"+
" Local project ID (metadata.json): %s\n"+
" Database %q project ID: %s\n\n"+
"The team server is serving a DIFFERENT project's database.\n"+
"This can happen when:\n"+
" - --database (or a --db name override) points at another project\n"+
" - the configured dolt_database was repointed after 'bd init'\n"+
" - the operator re-provisioned this database for another project\n\n"+
"Check dolt_database in .beads/metadata.json and any --database/--db\n"+
"override. 'bd init --team-server' re-adopts the provisioned identity\n"+
"and never writes to the shared database, so it is safe to re-run.",
expectedProjectID, database, dbProjectID)
}View on GitHub (pinned to 71377f2769)
Solutions
- Ask the operator to heal the database with 'bts migrate' (which writes the identity)
- Re-provision cleanly with 'bts init' if appropriate
- Never manually insert _project_id; let bts generate it
- Verify the database was not restored from an incomplete backup
Example fix
// before bd sync # database has no project identity // after bts migrate # operator heals identity metadata bd sync
Defensive patterns
Strategy: validation
Validate before calling
-- preflight: confirm identity row exists before connecting SELECT value FROM metadata WHERE `key` = '_project_id'; -- must return a non-empty row
Type guard
func isMissingIdentity(err error) bool {
return err != nil && strings.Contains(err.Error(), "has no project identity")
} Try / catch
err := bdSync(ctx)
if isMissingIdentity(err) {
// operator must heal/provision; client retry will not help
return fmt.Errorf("ask operator to run 'bts migrate' or 'bts init': %w", err)
} Prevention
- Never delete metadata._project_id rows manually
- Run 'bts migrate' to heal databases provisioned by older bts versions
- Verify backups include the metadata table before restoring
- Confirm 'bts init' completed successfully (exit 0) before admitting bd clients
When it happens
Trigger: verifyTeamServerSchema → checkTeamServerIdentity finds schema OK but GetMetadataInTx returns "" for _project_id — e.g. the database was provisioned by an older bts that never wrote identity, or the metadata row was deleted.
Common situations: Older bts database provisioned before identity stamping existed; someone manually deleted the _project_id row; database restored from a partial backup missing metadata; schema OK but 'bts init' was interrupted.
Related errors
- uow: team-server identity check on database %q: %w
- failed to reach the workspace identity: %v
- record repo_id: %w
- record clone_id: %w
- record last_import_time: %w
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/cca5163ebdf08596.
Report an issue: GitHub.