bytebase/bytebase · error

failed to list databases for project %q

Error message

failed to list databases for project %q

What it means

unfoldSpecTargets lazily loads all databases in the project via stores.ListDatabases when the caller passed a nil allDatabases slice. If the metadata-database query fails, the error is wrapped with the project resource name. This is a store-layer/database failure, not a problem with the spec targets themselves.

Source

Thrown at backend/component/review/evaluator.go:455

			for _, db := range matchedDatabases {
				unfolded = append(unfolded, db.ResourceName())
			}
			return unfolded, nil
		}
	}
	return dbTargets, nil
}

// unfoldSpecTargets unfolds database groups in specs and returns all database targets.
// allDatabases must be nil or the full unfiltered project database list; callers pass it
// through to keep database-group matching and direct database lookup on the same snapshot.
func unfoldSpecTargets(ctx context.Context, stores *store.Store, specs []*storepb.PlanConfig_Spec, projectID string, allDatabases []*store.DatabaseMessage, databaseGroup *v1pb.DatabaseGroup) ([]specTarget, error) {
	getAllDatabases := func() error {
		if allDatabases == nil {
			var err error
			allDatabases, err = stores.ListDatabases(ctx, &store.FindDatabaseMessage{ProjectID: &projectID})
			if err != nil {
				return errors.Wrapf(err, "failed to list databases for project %q", projectID)
			}
		}
		return nil
	}
	getDatabase := func(target string) (*store.DatabaseMessage, error) {
		targetProjectID, instanceID, databaseName, err := common.GetDatabaseResourceName(target)
		if err != nil {
			return nil, errors.Wrapf(err, "failed to parse database target %q", target)
		}
		if targetProjectID != nil && *targetProjectID != projectID {
			return nil, errors.Errorf("database target %q does not belong to project %q", target, projectID)
		}
		databases, err := stores.ListDatabases(ctx, &store.FindDatabaseMessage{
			ProjectID:    &projectID,
			InstanceID:   &instanceID,
			DatabaseName: &databaseName,
		})
		if err != nil {

View on GitHub (pinned to 1870550677)

Solutions

  1. Check that the metadata Postgres is running and reachable (PG_URL connectivity)
  2. Inspect server logs for the underlying wrapped store error to identify the query failure
  3. Retry the operation once connectivity is restored; ListDatabases failures are usually transient
  4. Verify the project resource name is well-formed (malformed project IDs can surface as query errors)
Defensive patterns

Strategy: try-catch

Try / catch

var unfolded []string
unfolded, err := unfoldSpecTargets(ctx, stores, specs, projectID, nil, nil)
if err != nil {
    var storeErr *store.ErrDatabaseList
    if errors.As(err, &storeErr) || strings.Contains(err.Error(), "failed to list databases") {
        // transient metadata-store failure: back off and retry
        time.Sleep(backoff)
        unfolded, err = unfoldSpecTargets(ctx, stores, specs, projectID, nil, nil)
    }
    if err != nil {
        return fmt.Errorf("unfold spec targets for %s: %w", projectID, err)
    }
}

Prevention

When it happens

Trigger: Calling unfoldSpecTargets with allDatabases == nil and the project has databases that must be listed; stores.ListDatabases(ctx, &store.FindDatabaseMessage{ProjectID: &projectID}) returns a non-nil error (metadata DB down, connection pool exhausted, query error).

Common situations: Postgres metadata database is temporarily unavailable or restarting; connection limit reached under load; network partition between the Bytebase server and its metadata database; corrupted metadata causing a scan error.

Understand the failure class

Background: Database query failed: Internal Server Error 500s wrapping SQL, Prisma, and connection failures — what to check first — this error's family across 16 libraries.

Related errors


AI-assisted analysis of bytebase/bytebase@1870550677 (2026-09-06). Data as JSON: /api/errors/9f6f5dc865996903. Report an issue: GitHub.