bytebase/bytebase · error

database %q does not belong to project %q

Error message

database %q does not belong to project %q

What it means

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.

Source

Thrown at backend/api/v1/rollout_service_task.go:276

			}
			for _, matched := range databaseGroup.MatchedDatabases {
				_, instanceID, databaseName, err := common.GetDatabaseResourceName(matched.Name)
				if err != nil {
					return nil, errors.Wrapf(err, "failed to parse %q", matched.Name)
				}
				database, err := s.GetDatabase(ctx, &store.FindDatabaseMessage{
					Workspace:    common.GetWorkspaceIDFromContext(ctx),
					InstanceID:   &instanceID,
					DatabaseName: &databaseName,
				})
				if err != nil {
					return nil, errors.Wrapf(err, "failed to get database")
				}
				if database == nil {
					return nil, errors.Errorf("database %q not found", matched.Name)
				}
				if database.ProjectID != targetProjectID {
					return nil, errors.Errorf("database %q does not belong to project %q", matched.Name, targetProjectID)
				}
				if database.ResourceName() != matched.Name {
					return nil, errors.Errorf("database target %q is not canonical for its instance", matched.Name)
				}
				databases = append(databases, database)
			}
		} else if targetProjectID, instanceID, databaseName, err := common.GetDatabaseResourceName(target); err == nil {
			database, err := s.GetDatabase(ctx, &store.FindDatabaseMessage{
				Workspace:    common.GetWorkspaceIDFromContext(ctx),
				InstanceID:   &instanceID,
				DatabaseName: &databaseName,
			})
			if err != nil {
				return nil, errors.Wrapf(err, "failed to get database")
			}
			if database == nil {
				return nil, errors.Errorf("database %q not found", target)
			}

View on GitHub (pinned to 1870550677)

Solutions

  1. Move the database back into the target project, or
  2. Adjust the group's match expression to exclude databases from other projects
  3. Update the plan's target to a group in the project that actually owns the databases
  4. Re-run plan creation after fixing ownership

Example fix

// before
// group in prj-a matches instances shared with prj-b
// after
// group expression: resource_group("env") && project == "prj-a" scope
Defensive patterns

Strategy: validation

Validate before calling

for _, t := range c.Targets {
    if pid, _, err := common.GetProjectIDDatabaseGroupID(t); err == nil {
        group, _ := getDatabaseGroupByName(ctx, s, t, v1pb.DatabaseGroupView_DATABASE_GROUP_VIEW_FULL)
        for _, m := range group.MatchedDatabases {
            // ensure each matched db's project equals pid before plan create
            _ = m
        }
    }
}

Try / catch

if err != nil && strings.Contains(err.Error(), "does not belong to project") {
    // show a project-ownership fix UI: move db or change group expression
    return errdef.FailedPrecondition(err)
}

Prevention

When it happens

Trigger: 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.

Common situations: Database moved between projects without updating the group; group defined in project A matching databases also matched by project B; project reorganization.

Understand the failure class

Background: Permission denied / not authorized / 403 Forbidden: access-control rejections when the caller lacks the required role, grant, or ownership — this error's family across 18 libraries.

Related errors


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