bytebase/bytebase · error

unsupported status %q

Error message

unsupported status %q

What it means

getAccessGrantStatusFilter maps a user-supplied status string from a CEL `status == "..."` / `status in [...]` filter to SQL, and throws this when the status is not one of ACTIVE, EXPIRED, REVOKED, PENDING, CANCELED, or REJECTED. These are virtual statuses: PENDING/CANCELED/REJECTED are derived from issue approval state, not stored directly in access_grant.status.

Source

Thrown at backend/store/access_grant.go:567

func getAccessGrantStatusFilter(status string) (*qb.Query, error) {
	rejectedIssueQ := qb.Q().Space("EXISTS (SELECT 1 FROM issue, jsonb_array_elements(issue.payload->'approval'->'approvers') AS approver WHERE issue.project = access_grant.project AND issue.id = (access_grant.payload->>'issueId')::bigint AND COALESCE((issue.payload->'approval'->>'approvalFindingDone')::boolean, false) AND issue.payload->'approval'->'approvalTemplate' IS NOT NULL AND approver->>'status' = ?)", storepb.IssuePayloadApproval_Approver_REJECTED.String())
	canceledIssueQ := qb.Q().Space("EXISTS (SELECT 1 FROM issue WHERE issue.project = access_grant.project AND issue.id = (access_grant.payload->>'issueId')::bigint AND issue.status = ?)", storepb.Issue_CANCELED.String())

	switch status {
	case "ACTIVE":
		return qb.Q().Space("(access_grant.status = ? AND access_grant.expire_time > now())", storepb.AccessGrant_ACTIVE.String()), nil
	case "EXPIRED":
		return qb.Q().Space("(access_grant.status = ? AND access_grant.expire_time <= now())", storepb.AccessGrant_ACTIVE.String()), nil
	case "REVOKED":
		return qb.Q().Space("access_grant.status = ?", storepb.AccessGrant_REVOKED.String()), nil
	case "PENDING":
		return qb.Q().Space("(access_grant.status = ? AND NOT ? AND NOT ?)", storepb.AccessGrant_PENDING.String(), canceledIssueQ, rejectedIssueQ), nil
	case "CANCELED":
		return qb.Q().Space("(access_grant.status = ? AND ? AND NOT ?)", storepb.AccessGrant_PENDING.String(), canceledIssueQ, rejectedIssueQ), nil
	case "REJECTED":
		return qb.Q().Space("(access_grant.status = ? AND ?)", storepb.AccessGrant_PENDING.String(), rejectedIssueQ), nil
	default:
		return nil, errors.Errorf("unsupported status %q", status)
	}
}

View on GitHub (pinned to 1870550677)

Solutions

  1. Use one of the exact values: ACTIVE, EXPIRED, REVOKED, PENDING, CANCELED, REJECTED (uppercase, no prefix)
  2. Check the ListAccessGrants API reference for the documented status filter vocabulary
  3. If combining statuses, use `status in ["ACTIVE", "PENDING"]` instead of inventing intermediate values

Example fix

// before
filter = "status == \"active\""
// after
filter = "status == \"ACTIVE\""
Defensive patterns

Strategy: validation

Validate before calling

var validStatuses = map[string]bool{"ACTIVE":true,"EXPIRED":true,"REVOKED":true,"PENDING":true,"CANCELED":true,"REJECTED":true}
if !validStatuses[status] {
    return fmt.Errorf("status %q not in %v", status, []string{"ACTIVE","EXPIRED","REVOKED","PENDING","CANCELED","REJECTED"})
}

Try / catch

if err := validateAccessGrantStatuses(filterStatuses); err != nil {
    return status.Errorf(codes.InvalidArgument, "unsupported status filter: %v", err)
}

Prevention

When it happens

Trigger: Filtering access grants with a status literal not in the supported set, e.g. `status == "active"` (lowercase), `status == "PENDING_APPROVAL"`, or a proto enum name like `STATUS_ACTIVE`.

Common situations: Case-sensitivity mistakes (lowercase status), clients reusing status enums from other Bytebase resources (issues, instances), or API version drift after the status vocabulary changed.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


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