{"record":{"id":"8250457839cb856e","repo":"bytebase/bytebase","slug":"expect-bool-result-for-masking-rule","errorCode":null,"errorMessage":"expect bool result for masking rule","messagePattern":"expect bool result for masking rule","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"backend/api/v1/masking_evaluator.go","lineNumber":314,"sourceCode":"\tmaskingRulePolicyEnv, err := cel.NewEnv(common.MaskingRulePolicyCELAttributes...)\n\tif err != nil {\n\t\treturn false, errors.Wrapf(err, \"failed to create CEL environment for masking rule policy\")\n\t}\n\tast, issues := maskingRulePolicyEnv.Compile(expression)\n\tif issues != nil && issues.Err() != nil {\n\t\treturn false, errors.Wrapf(issues.Err(), \"failed to get the ast of CEL program for masking rule\")\n\t}\n\tprg, err := maskingRulePolicyEnv.Program(ast)\n\tif err != nil {\n\t\treturn false, errors.Wrapf(err, \"failed to create CEL program for masking rule\")\n\t}\n\tout, _, err := prg.Eval(attributes)\n\tif err != nil {\n\t\treturn false, errors.Wrapf(err, \"failed to eval CEL program for masking rule\")\n\t}\n\tval, err := out.ConvertToNative(reflect.TypeFor[bool]())\n\tif err != nil {\n\t\treturn false, errors.Wrap(err, \"expect bool result for masking rule\")\n\t}\n\tboolVar, ok := val.(bool)\n\tif !ok {\n\t\treturn false, errors.Wrap(err, \"expect bool result for masking rule\")\n\t}\n\treturn boolVar, nil\n}\n\nfunc evaluateQueryExportPolicyCondition(expression string, attributes map[string]any) (bool, error) {\n\tif expression == \"\" {\n\t\treturn true, nil\n\t}\n\tenv, err := cel.NewEnv(common.IAMPolicyConditionCELAttributes...)\n\tif err != nil {\n\t\treturn false, err\n\t}\n\tast, issues := env.Compile(expression)\n\tif issues != nil && issues.Err() != nil {","sourceCodeStart":296,"sourceCodeEnd":332,"githubUrl":"https://github.com/bytebase/bytebase/blob/1870550677fe08f0d2a78c07acd27541464eb945/backend/api/v1/masking_evaluator.go#L296-L332","documentation":"The masking rule expression evaluated but its result cannot be converted to a Go bool via ConvertToNative(reflect.TypeFor[bool]()). Masking rules must be boolean conditions; an expression returning a string, int, or list triggers this. It signals the stored expression has the wrong return type, not an evaluation malfunction.","triggerScenarios":"evaluateMaskingRulePolicyCondition at backend/api/v1/masking_evaluator.go:312-314: out.ConvertToNative fails because the masking rule's top-level expression is a non-bool value (e.g. a bare `resource.database_id` or an arithmetic/string expression).","commonSituations":"Admin pasted a non-boolean expression (e.g. a projection like `resource.column.name`) into the masking rule field; a truncated expression lost its comparison operator (`resource.database_id == \"x\"` saved as `resource.database_id == \"x\" &&` then 'fixed' by deleting the operand side).","solutions":["Rewrite the stored masking rule so it yields a boolean (complete comparison, logical expression, or has()/matches() predicate)","Enforce bool output at save time: compile with a cel.Checks/OutputType(cel.BoolType) expectation and reject non-bool rules in the API","Use common.ValidateMaskingRuleCELExpr when importing or editing rules to catch wrong return types before persistence"],"exampleFix":"// before (rule expression)\nresource.database_id\n// after\nresource.database_id == \"db-prod\"","handlingStrategy":"validation","validationCode":"ast, issues := env.Compile(expr)\nif issues != nil && issues.Err() != nil { return issues.Err() }\nif ast.OutputType() != cel.BoolType {\n\treturn errors.New(\"masking rule must evaluate to a boolean\")\n}","typeGuard":"func maskingRuleIsBool(env *cel.Env, expr string) bool {\n\tast, issues := env.Compile(expr)\n\tif issues != nil && issues.Err() != nil { return false }\n\treturn ast.OutputType() == cel.BoolType\n}","tryCatchPattern":"pass, err := evaluateMaskingRulePolicyCondition(expr, attrs)\nif err != nil {\n\treturn false, errors.Wrapf(err, \"masking rule %q must be boolean\", expr)\n}","preventionTips":["Reject non-boolean masking rules at save time using output type checking","Document that rules are boolean conditions and show valid examples in the editor","Add a compile check for output type in the import/export rule pipeline"],"tags":["cel","type-mismatch","policy-engine","go"],"backgroundTag":"type-mismatch","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"}