{"record":{"id":"9f6f5dc865996903","repo":"bytebase/bytebase","slug":"failed-to-list-databases-for-project-q","errorCode":null,"errorMessage":"failed to list databases for project %q","messagePattern":"failed to list databases for project %q","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"backend/component/review/evaluator.go","lineNumber":455,"sourceCode":"\t\t\tfor _, db := range matchedDatabases {\n\t\t\t\tunfolded = append(unfolded, db.ResourceName())\n\t\t\t}\n\t\t\treturn unfolded, nil\n\t\t}\n\t}\n\treturn dbTargets, nil\n}\n\n// unfoldSpecTargets unfolds database groups in specs and returns all database targets.\n// allDatabases must be nil or the full unfiltered project database list; callers pass it\n// through to keep database-group matching and direct database lookup on the same snapshot.\nfunc unfoldSpecTargets(ctx context.Context, stores *store.Store, specs []*storepb.PlanConfig_Spec, projectID string, allDatabases []*store.DatabaseMessage, databaseGroup *v1pb.DatabaseGroup) ([]specTarget, error) {\n\tgetAllDatabases := func() error {\n\t\tif allDatabases == nil {\n\t\t\tvar err error\n\t\t\tallDatabases, err = stores.ListDatabases(ctx, &store.FindDatabaseMessage{ProjectID: &projectID})\n\t\t\tif err != nil {\n\t\t\t\treturn errors.Wrapf(err, \"failed to list databases for project %q\", projectID)\n\t\t\t}\n\t\t}\n\t\treturn nil\n\t}\n\tgetDatabase := func(target string) (*store.DatabaseMessage, error) {\n\t\ttargetProjectID, instanceID, databaseName, err := common.GetDatabaseResourceName(target)\n\t\tif err != nil {\n\t\t\treturn nil, errors.Wrapf(err, \"failed to parse database target %q\", target)\n\t\t}\n\t\tif targetProjectID != nil && *targetProjectID != projectID {\n\t\t\treturn nil, errors.Errorf(\"database target %q does not belong to project %q\", target, projectID)\n\t\t}\n\t\tdatabases, err := stores.ListDatabases(ctx, &store.FindDatabaseMessage{\n\t\t\tProjectID:    &projectID,\n\t\t\tInstanceID:   &instanceID,\n\t\t\tDatabaseName: &databaseName,\n\t\t})\n\t\tif err != nil {","sourceCodeStart":437,"sourceCodeEnd":473,"githubUrl":"https://github.com/bytebase/bytebase/blob/1870550677fe08f0d2a78c07acd27541464eb945/backend/component/review/evaluator.go#L437-L473","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","solutions":["Check that the metadata Postgres is running and reachable (PG_URL connectivity)","Inspect server logs for the underlying wrapped store error to identify the query failure","Retry the operation once connectivity is restored; ListDatabases failures are usually transient","Verify the project resource name is well-formed (malformed project IDs can surface as query errors)"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"var unfolded []string\nunfolded, err := unfoldSpecTargets(ctx, stores, specs, projectID, nil, nil)\nif err != nil {\n    var storeErr *store.ErrDatabaseList\n    if errors.As(err, &storeErr) || strings.Contains(err.Error(), \"failed to list databases\") {\n        // transient metadata-store failure: back off and retry\n        time.Sleep(backoff)\n        unfolded, err = unfoldSpecTargets(ctx, stores, specs, projectID, nil, nil)\n    }\n    if err != nil {\n        return fmt.Errorf(\"unfold spec targets for %s: %w\", projectID, err)\n    }\n}","preventionTips":["Monitor metadata Postgres health and alert on connection failures","Pass a pre-fetched allDatabases slice when evaluating many specs to reduce repeated store queries","Set sane connection-pool limits for the metadata DB","Retry transient store errors with exponential backoff"],"tags":["database","metadata-store","project","lazy-loading"],"backgroundTag":"database-query-failed","analyzedSha":"1870550677fe08f0d2a78c07acd27541464eb945","analyzedAt":"2026-09-06T21:16:13.665Z","contentChangedAt":"2026-09-06T21:16:13.665Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}