{"record":{"id":"ad0e63e5d6ff4481","repo":"bytebase/bytebase","slug":"database-q-does-not-belong-to-project-q","errorCode":null,"errorMessage":"database %q does not belong to project %q","messagePattern":"database %q does not belong to project %q","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"backend/api/v1/rollout_service_task.go","lineNumber":276,"sourceCode":"\t\t\t}\n\t\t\tfor _, matched := range databaseGroup.MatchedDatabases {\n\t\t\t\t_, instanceID, databaseName, err := common.GetDatabaseResourceName(matched.Name)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn nil, errors.Wrapf(err, \"failed to parse %q\", matched.Name)\n\t\t\t\t}\n\t\t\t\tdatabase, err := s.GetDatabase(ctx, &store.FindDatabaseMessage{\n\t\t\t\t\tWorkspace:    common.GetWorkspaceIDFromContext(ctx),\n\t\t\t\t\tInstanceID:   &instanceID,\n\t\t\t\t\tDatabaseName: &databaseName,\n\t\t\t\t})\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn nil, errors.Wrapf(err, \"failed to get database\")\n\t\t\t\t}\n\t\t\t\tif database == nil {\n\t\t\t\t\treturn nil, errors.Errorf(\"database %q not found\", matched.Name)\n\t\t\t\t}\n\t\t\t\tif database.ProjectID != targetProjectID {\n\t\t\t\t\treturn nil, errors.Errorf(\"database %q does not belong to project %q\", matched.Name, targetProjectID)\n\t\t\t\t}\n\t\t\t\tif database.ResourceName() != matched.Name {\n\t\t\t\t\treturn nil, errors.Errorf(\"database target %q is not canonical for its instance\", matched.Name)\n\t\t\t\t}\n\t\t\t\tdatabases = append(databases, database)\n\t\t\t}\n\t\t} else if targetProjectID, instanceID, databaseName, err := common.GetDatabaseResourceName(target); err == nil {\n\t\t\tdatabase, err := s.GetDatabase(ctx, &store.FindDatabaseMessage{\n\t\t\t\tWorkspace:    common.GetWorkspaceIDFromContext(ctx),\n\t\t\t\tInstanceID:   &instanceID,\n\t\t\t\tDatabaseName: &databaseName,\n\t\t\t})\n\t\t\tif err != nil {\n\t\t\t\treturn nil, errors.Wrapf(err, \"failed to get database\")\n\t\t\t}\n\t\t\tif database == nil {\n\t\t\t\treturn nil, errors.Errorf(\"database %q not found\", target)\n\t\t\t}","sourceCodeStart":258,"sourceCodeEnd":294,"githubUrl":"https://github.com/bytebase/bytebase/blob/1870550677fe08f0d2a78c07acd27541464eb945/backend/api/v1/rollout_service_task.go#L258-L294","documentation":"Returned when a database matched by a database group exists but belongs to a different project than the project that owns the group target. Group targets are namespaced by project, so every matched database must live in that same project.","triggerScenarios":"A database group's matcher expression matches databases that were moved to another project, then a plan create resolves targets and finds database.ProjectID != targetProjectID.","commonSituations":"Database moved between projects without updating the group; group defined in project A matching databases also matched by project B; project reorganization.","solutions":["Move the database back into the target project, or","Adjust the group's match expression to exclude databases from other projects","Update the plan's target to a group in the project that actually owns the databases","Re-run plan creation after fixing ownership"],"exampleFix":"// before\n// group in prj-a matches instances shared with prj-b\n// after\n// group expression: resource_group(\"env\") && project == \"prj-a\" scope","handlingStrategy":"validation","validationCode":"for _, t := range c.Targets {\n    if pid, _, err := common.GetProjectIDDatabaseGroupID(t); err == nil {\n        group, _ := getDatabaseGroupByName(ctx, s, t, v1pb.DatabaseGroupView_DATABASE_GROUP_VIEW_FULL)\n        for _, m := range group.MatchedDatabases {\n            // ensure each matched db's project equals pid before plan create\n            _ = m\n        }\n    }\n}","typeGuard":null,"tryCatchPattern":"if err != nil && strings.Contains(err.Error(), \"does not belong to project\") {\n    // show a project-ownership fix UI: move db or change group expression\n    return errdef.FailedPrecondition(err)\n}","preventionTips":["Move databases between projects only with a group-membership refresh afterwards","Scope group match expressions so they cannot cross project boundaries","Audit groups whose matches include databases from other projects"],"tags":["database-group","project","ownership","validation"],"backgroundTag":"permission-denied","analyzedSha":"1870550677fe08f0d2a78c07acd27541464eb945","analyzedAt":"2026-09-06T21:16:13.665Z","contentChangedAt":"2026-09-06T21:16:13.665Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}