gastownhall/beads · error

database %q has no project identity (config.issue_prefix) —

Error message

database %q has no project identity (config.issue_prefix) — provision it with 'bts init' (or heal an older bts database with 'bts migrate')

What it means

adoptTeamServerIdentity reads the project identity provisioned by the team server (bts). When VerifyIdentity succeeds (readErr == nil) but resolveInitIssuePrefix finds no config.issue_prefix, bd hard-errors: in team-server mode bd never writes identity itself, so an unprovisioned shared database is unusable until bts provisions it.

Source

Thrown at cmd/bd/init_proxied_server.go:421

			return "", fmt.Errorf("create remote origin: %w", err)
		}
		return "", nil
	})
}

// adoptTeamServerIdentity reads the bts-provisioned identity out of the shared
// database, following the gateway contract: adopt if present, hard error if
// absent — bd never writes identity in team-server mode.
//
// ABSENT means "unprovisioned, tell them to run bts init" and UNREADABLE means
// "the connection failed, say so"; keeping those apart is the InitVerifier
// role's promise. The two markers arrive as ONE snapshot, so the prefix and the
// project id cannot come from either side of a concurrent write.
func adoptTeamServerIdentity(ctx context.Context, verifier issueops.InitVerifier, dbName, localPrefix string, prefixIsExplicit bool, localProjectID string) (prefix, projectID string, err error) {
	identity, readErr := verifier.VerifyIdentity(ctx, issueops.VerifyIdentityRequest{})
	if _, err := resolveInitIssuePrefix(true, identity.Prefix, dbName, localPrefix, readErr); err != nil {
		if readErr == nil {
			return "", "", fmt.Errorf(
				"database %q has no project identity (config.issue_prefix) — provision it with 'bts init' (or heal an older bts database with 'bts migrate')",
				dbName)
		}
		return "", "", err
	}
	// An explicit --prefix that disagrees must not be silently ignored; a
	// merely derived prefix adopts silently.
	if prefixIsExplicit && identity.Prefix != localPrefix {
		return "", "", fmt.Errorf(
			"--prefix %q conflicts with issue_prefix %q provisioned in database %q; omit --prefix to adopt the provisioned one",
			localPrefix, identity.Prefix, dbName)
	}

	adoptedID, _, err := resolveInitProjectID(true, localProjectID, identity.ProjectID, dbName, readErr)
	if err != nil {
		if readErr == nil {
			return "", "", fmt.Errorf(
				"database %q has no project identity (metadata._project_id) — provision it with 'bts init' (or heal an older bts database with 'bts migrate')",

View on GitHub (pinned to 71377f2769)

Solutions

  1. Run 'bts init' against the shared database to provision its project identity
  2. For an older shared database, run 'bts migrate' to heal it, then re-run bd init
  3. Verify you are pointed at the correct, provisioned database (check the Dolt database name in config)

Example fix

// before
err: database "bd_team" has no project identity (config.issue_prefix)
// after
bts init --database bd_team   # provision identity on the shared db
bd init
Defensive patterns

Strategy: validation

Validate before calling

// before bd init, confirm the shared db is provisioned
ident, err := verifier.VerifyIdentity(ctx, issueops.VerifyIdentityRequest{})
if err != nil || ident.Prefix == "" {
    return errors.New("database not provisioned; run 'bts init' (or 'bts migrate') first")
}

Try / catch

if err != nil && strings.Contains(err.Error(), "has no project identity (config.issue_prefix)") {
    // run bts init (fresh db) or bts migrate (legacy db), then retry bd init
}

Prevention

When it happens

Trigger: Running bd init against a team-server Dolt database that has no config.issue_prefix — the database was created but never provisioned by 'bts init', or is an old bts database predating identity provisioning.

Common situations: Pointing bd at a fresh/empty Dolt database; connecting to a legacy shared database that needs migration; wrong database name resolving to an unprovisioned one.

Related errors


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