gastownhall/beads · error

hosted database %q has no provisioned project identity (_pro

Error message

hosted database %q has no provisioned project identity (_project_id) -- provisioning-contract violation; bd will not mint an identity for a hosted database

What it means

In gateway mode, if the hosted database reads successfully but contains no provisioned _project_id, init refuses to mint an identity — minting locally would diverge across clones and cause PROJECT IDENTITY MISMATCH on later opens. This is flagged as a provisioning-contract violation.

Source

Thrown at cmd/bd/init.go:149

// A missing server id is a provisioning-contract violation bd will not mint
// over — even when a local id already exists — and a read error is surfaced as
// the transient failure it is, so a flaky connection is not misdiagnosed as an
// unprovisioned database.
//
// Non-gateway (legacy, unchanged): a non-empty localID is kept as-is (readErr
// ignored, exactly as before); otherwise an adopted id wins (another rig already
// chose it; minting a new one would break cross-project verification), else a
// fresh identity is generated.
func resolveInitProjectID(gateway bool, localID, adoptedFromDB, dbName string, readErr error) (value string, changed bool, err error) {
	if gateway {
		if adoptedFromDB != "" {
			return adoptedFromDB, adoptedFromDB != localID, nil
		}
		if readErr != nil {
			return "", false, fmt.Errorf(
				"reading project identity (_project_id) from hosted database %q: %w", dbName, readErr)
		}
		return "", false, fmt.Errorf(
			"hosted database %q has no provisioned project identity (_project_id) -- "+
				"provisioning-contract violation; bd will not mint an identity for a hosted database",
			dbName)
	}
	if localID != "" {
		return localID, false, nil
	}
	if adoptedFromDB != "" {
		return adoptedFromDB, true, nil
	}
	return configfile.GenerateProjectID(), true, nil
}

// shouldConsultInitProjectID reports whether init must read _project_id from the
// database before resolving the local identity.
//
// Gateway: always — the hosted server owns the identity, so init reconciles it on
// every run, including a re-init or preseeded metadata.json that already carries a

View on GitHub (pinned to 71377f2769)

Solutions

  1. Re-provision the database server-side so _project_id exists, then re-run `bd init`
  2. Verify the --database/connection targets the correct provisioned hosted DB
  3. Have the host operator set _project_id in the hosted DB deliberately
  4. Do NOT run `bd doctor --fix` from multiple clones to backfill — settle identity deliberately from the clone that should win

Example fix

// before: gateway DB without _project_id
bd init  # fails: hosted database "xyz" has no provisioned project identity (_project_id)
// after: host re-provisions server-side; then
bd init
Defensive patterns

Strategy: validation

Validate before calling

// Before gateway init, verify the hosted DB has a project identity
pid, err := readConfigFromHostedDB(dbName, "_project_id")
if err != nil { return err }
if strings.TrimSpace(pid) == "" {
    return fmt.Errorf("hosted DB %s lacks _project_id: re-provision server-side", dbName)
}

Prevention

When it happens

Trigger: `bd init` in gateway mode where the _project_id read succeeds but returns empty (adoptedFromDB == "", readErr == nil) — the hosted DB was never provisioned with a project identity.

Common situations: Database created manually/out-of-band without provisioning; host-side reset dropped _project_id; pointing at the wrong database name; legacy backend predating identity provisioning. Doing `bd doctor --fix` here is dangerous: whichever clone runs it first backfills, and others then hard-fail on open.

Related errors


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