bytebase/bytebase · error
export value must be a boolean
Error message
export value must be a boolean
What it means
For `export == <value>` the compiler asserts a Go bool literal, producing the predicate COALESCE((payload->>'export')::boolean, false) = ?. Non-bool literals (strings, numbers) are rejected with this error.
Source
Thrown at backend/store/access_grant.go:453
return nil, errors.Wrapf(err, "invalid issue name %q", issueStr)
}
return qb.Q().Space("(access_grant.payload->>'issueId')::bigint = ?", issueUID), nil
case "target":
targetStr, ok := value.(string)
if !ok {
return nil, errors.Errorf("target value must be a string")
}
return qb.Q().Space("access_grant.payload->'targets' @> jsonb_build_array(to_jsonb(?::text))", targetStr), nil
case "unmask":
boolVal, ok := value.(bool)
if !ok {
return nil, errors.Errorf("unmask value must be a boolean")
}
return qb.Q().Space("COALESCE((access_grant.payload->>'unmask')::boolean, false) = ?", boolVal), nil
case "export":
boolVal, ok := value.(bool)
if !ok {
return nil, errors.Errorf("export value must be a boolean")
}
return qb.Q().Space("COALESCE((access_grant.payload->>'export')::boolean, false) = ?", boolVal), nil
default:
return nil, errors.Errorf("unsupported variable %q", variable)
}
case celoverloads.Contains:
call := expr.AsCall()
target := call.Target()
if target.Kind() != celast.IdentKind {
return nil, errors.Errorf("contains target must be an identifier")
}
variable := target.AsIdent()
if variable != "query" {
return nil, errors.Errorf("contains is not supported on field %q", variable)
}
args := call.Args()
if len(args) != 1 || args[0].Kind() != celast.LiteralKind {
return nil, errors.Errorf("contains requires a single string literal argument")View on GitHub (pinned to 1870550677)
Solutions
- Write the filter with bare booleans: `export == true` / `export == false`.
- Fix the value source so booleans stay typed (JSON bool, Go bool) rather than "true"/"false" strings.
- Format bool values with %t, not %q or %v on a string, when generating the filter.
Example fix
// before
filter := fmt.Sprintf("export == %v", exportStr) // "true"
// after
filter := fmt.Sprintf("export == %t", exportBool) Defensive patterns
Strategy: type-guard
Validate before calling
if _, ok := exportValue.(bool); !ok {
return fmt.Errorf("export filter value must be a bool, got %T", exportValue)
} Type guard
func isBool(v any) bool {
_, ok := v.(bool)
return ok
} Try / catch
if _, err := store.ListAccessGrants(ctx, filter); err != nil {
if strings.Contains(err.Error(), "export value must be a boolean") {
return status.Error(codes.InvalidArgument, "export must be true or false, unquoted")
}
return err
} Prevention
- Keep bools typed end-to-end (JSON bool -> Go bool -> CEL bool)
- Use %t formatting for booleans in generated filter strings
- Reject "true"/"false" strings at the config boundary
- Unit-test each boolean filter field
When it happens
Trigger: ListAccessGrants filter like `export == "true"`, `export == 0`, or `export == null`.
Common situations: Same as the unmask case: string-serialized booleans from JSON/env config, over-quoted templated filters, and client SDKs that stringify bools.
Understand the failure class
Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.
Related errors
- unmask value must be a boolean
- "has_rollout" should be bool
- invalid starred value %v, expect true or false
- invalid shared value %v, expect true or false
- CodeInvalidArgument
AI-assisted analysis of bytebase/bytebase@1870550677 (2026-09-06).
Data as JSON: /api/errors/5dc674b726ea604e.
Report an issue: GitHub.