{"record":{"id":"2ae3934aee4c3136","repo":"gastownhall/beads","slug":"database-q-has-no-project-identity-config-issue","errorCode":null,"errorMessage":"database %q has no project identity (config.issue_prefix) — provision it with 'bts init' (or heal an older bts database with 'bts migrate')","messagePattern":"database %q has no project identity \\(config\\.issue_prefix\\) — provision it with 'bts init' \\(or heal an older bts database with 'bts migrate'\\)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/bd/init_proxied_server.go","lineNumber":421,"sourceCode":"\t\t\treturn \"\", fmt.Errorf(\"create remote origin: %w\", err)\n\t\t}\n\t\treturn \"\", nil\n\t})\n}\n\n// adoptTeamServerIdentity reads the bts-provisioned identity out of the shared\n// database, following the gateway contract: adopt if present, hard error if\n// absent — bd never writes identity in team-server mode.\n//\n// ABSENT means \"unprovisioned, tell them to run bts init\" and UNREADABLE means\n// \"the connection failed, say so\"; keeping those apart is the InitVerifier\n// role's promise. The two markers arrive as ONE snapshot, so the prefix and the\n// project id cannot come from either side of a concurrent write.\nfunc adoptTeamServerIdentity(ctx context.Context, verifier issueops.InitVerifier, dbName, localPrefix string, prefixIsExplicit bool, localProjectID string) (prefix, projectID string, err error) {\n\tidentity, readErr := verifier.VerifyIdentity(ctx, issueops.VerifyIdentityRequest{})\n\tif _, err := resolveInitIssuePrefix(true, identity.Prefix, dbName, localPrefix, readErr); err != nil {\n\t\tif readErr == nil {\n\t\t\treturn \"\", \"\", fmt.Errorf(\n\t\t\t\t\"database %q has no project identity (config.issue_prefix) — provision it with 'bts init' (or heal an older bts database with 'bts migrate')\",\n\t\t\t\tdbName)\n\t\t}\n\t\treturn \"\", \"\", err\n\t}\n\t// An explicit --prefix that disagrees must not be silently ignored; a\n\t// merely derived prefix adopts silently.\n\tif prefixIsExplicit && identity.Prefix != localPrefix {\n\t\treturn \"\", \"\", fmt.Errorf(\n\t\t\t\"--prefix %q conflicts with issue_prefix %q provisioned in database %q; omit --prefix to adopt the provisioned one\",\n\t\t\tlocalPrefix, identity.Prefix, dbName)\n\t}\n\n\tadoptedID, _, err := resolveInitProjectID(true, localProjectID, identity.ProjectID, dbName, readErr)\n\tif err != nil {\n\t\tif readErr == nil {\n\t\t\treturn \"\", \"\", fmt.Errorf(\n\t\t\t\t\"database %q has no project identity (metadata._project_id) — provision it with 'bts init' (or heal an older bts database with 'bts migrate')\",","sourceCodeStart":403,"sourceCodeEnd":439,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/cmd/bd/init_proxied_server.go#L403-L439","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Run 'bts init' against the shared database to provision its project identity","For an older shared database, run 'bts migrate' to heal it, then re-run bd init","Verify you are pointed at the correct, provisioned database (check the Dolt database name in config)"],"exampleFix":"// before\nerr: database \"bd_team\" has no project identity (config.issue_prefix)\n// after\nbts init --database bd_team   # provision identity on the shared db\nbd init","handlingStrategy":"validation","validationCode":"// before bd init, confirm the shared db is provisioned\nident, err := verifier.VerifyIdentity(ctx, issueops.VerifyIdentityRequest{})\nif err != nil || ident.Prefix == \"\" {\n    return errors.New(\"database not provisioned; run 'bts init' (or 'bts migrate') first\")\n}","typeGuard":null,"tryCatchPattern":"if err != nil && strings.Contains(err.Error(), \"has no project identity (config.issue_prefix)\") {\n    // run bts init (fresh db) or bts migrate (legacy db), then retry bd init\n}","preventionTips":["Always run 'bts init' on a shared database before connecting bd to it","Run 'bts migrate' on pre-identity legacy databases","Double-check the database name — wrong name often means an unprovisioned db","In team-server mode, bd never writes identity: provisioning is bts's job"],"tags":["init","identity","team-server","unprovisioned-database","bts"],"backgroundTag":"unprovisioned-team-server-database","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}