bytebase/bytebase · error

unsupported variable %q

Error message

unsupported variable %q

What it means

The saved-query filter translator only supports the variable `creator` in equality comparisons. When it extracts the variable name from a CEL ==/!= expression and it is anything else, it rejects the filter with "unsupported variable". The filter schema for listing saved queries is deliberately narrow, so unknown fields are hard errors rather than being silently ignored.

Source

Thrown at backend/store/saved_query.go:946

				if err != nil {
					return nil, err
				}
				q.Or("?", qq)
			}
			return qb.Q().Space("(?)", q), nil
		case celoperators.LogicalAnd:
			for _, arg := range expr.AsCall().Args() {
				qq, err := getFilter(arg)
				if err != nil {
					return nil, err
				}
				q.And("?", qq)
			}
			return qb.Q().Space("(?)", q), nil
		case celoperators.Equals, celoperators.NotEquals:
			variable, value := getVariableAndValueFromExpr(expr)
			if variable != "creator" {
				return nil, errors.Errorf("unsupported variable %q", variable)
			}
			creator, ok := value.(string)
			if !ok {
				return nil, errors.Errorf("invalid creator value %q", value)
			}
			creatorEmail := strings.TrimPrefix(creator, "users/")
			if creatorEmail == "" {
				return nil, errors.New("invalid empty creator identifier")
			}
			if functionName == celoperators.Equals {
				return qb.Q().Space("saved_query.creator = ?", creatorEmail), nil
			}
			return qb.Q().Space("saved_query.creator != ?", creatorEmail), nil
		default:
			return nil, errors.Errorf("unexpected function %v", functionName)
		}
	}

View on GitHub (pinned to 1870550677)

Solutions

  1. Use only `creator` in the saved-query filter, e.g. `creator == "users/foo@example.com"`.
  2. Drop the unsupported predicate and filter other fields client-side after listing.
  3. Check the API documentation for the exact set of supported filter variables for this endpoint.
  4. If server-side filtering on another field is needed, extend the switch in backend/store/saved_query.go to map that variable to a column.

Example fix

// before
filter = "title == \"daily\""
// after
filter = "creator == \"users/foo@example.com\""
Defensive patterns

Strategy: validation

Validate before calling

const supportedVars = new Set(["creator"])
function validateFilter(filter) {
  for (const v of extractVariables(filter)) {
    if (!supportedVars.has(v)) throw new Error(`unsupported variable '${v}'; only 'creator' is supported`)
  }
}

Try / catch

try {
  await listSavedQueries({ filter })
} catch (e) {
  if (String(e).includes("unsupported variable")) {
    // fall back to listing without filter and filter client-side
    return listSavedQueries({}) 
  }
  throw e
}

Prevention

When it happens

Trigger: Listing saved queries with a filter comparing any variable other than `creator`, e.g. `name == "savedQueries/abc"`, `title == "x"`, or `project == "projects/1"` in the `filter` parameter.

Common situations: Developers assuming full CEL filtering support and filtering on fields like title or updatedAt; copying filter expressions from other Bytebase resources (databases, issues) that support more variables; typos like `creater == ...`.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


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