{"record":{"id":"e2276ae1d523183f","repo":"bytebase/bytebase","slug":"failed-to-eval-cel-program-for-masking-exemption-p","errorCode":null,"errorMessage":"failed to eval CEL program for masking exemption policy","messagePattern":"failed to eval CEL program for masking exemption policy","errorType":"error_code","errorClass":null,"httpStatus":500,"severity":"error","filePath":"backend/api/v1/masking_evaluator.go","lineNumber":260,"sourceCode":"\tmaskingExemptionPolicyEnv, err := cel.NewEnv(\n\t\tcel.Variable(\"resource\", cel.MapType(cel.StringType, cel.AnyType)),\n\t\tcel.Variable(\"request\", cel.MapType(cel.StringType, cel.AnyType)),\n\t\text.Strings(),\n\t)\n\tif err != nil {\n\t\treturn false, errors.Wrapf(err, \"failed to create CEL environment for masking exemption policy\")\n\t}\n\tast, issues := maskingExemptionPolicyEnv.Compile(expression.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 exemption policy\")\n\t}\n\tprg, err := maskingExemptionPolicyEnv.Program(ast)\n\tif err != nil {\n\t\treturn false, errors.Wrapf(err, \"failed to create CEL program for masking exemption policy\")\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 exemption policy\")\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 exemption policy\")\n\t}\n\tboolVar, ok := val.(bool)\n\tif !ok {\n\t\treturn false, errors.Wrap(err, \"expect bool result for masking exemption policy\")\n\t}\n\treturn boolVar, nil\n}\n\nfunc getAlgorithmNameFromSemanticType(semanticType *storepb.SemanticTypeSetting_SemanticType) string {\n\tif semanticType == nil || semanticType.Algorithm == nil {\n\t\treturn \"\"\n\t}\n\n\tswitch semanticType.Algorithm.Mask.(type) {","sourceCodeStart":242,"sourceCodeEnd":278,"githubUrl":"https://github.com/bytebase/bytebase/blob/1870550677fe08f0d2a78c07acd27541464eb945/backend/api/v1/masking_evaluator.go#L242-L278","documentation":"prg.Eval(attributes) returned a runtime error while evaluating the masking exemption policy CEL expression. Compile only checks syntax and types against declared variables; runtime failures happen when the expression performs an unsupported operation on the actual attribute values (type errors on any-typed values, missing map keys with strict semantics, extension function misuse, evaluation timeouts, recursion).","triggerScenarios":"In evaluateMaskingExemptionPolicyCondition (backend/api/v1/masking_evaluator.go:258), the stored exemption policy expression evaluates against the masking exemption attributes map (resource.database_name, resource.schema_name, resource.table_name, resource.column_name, resource.classification_level, request.time) and hits an unhandled runtime condition, e.g. comparing request.time with a wrong format or calling a string ext function on a non-string.","commonSituations":"Admin saved an exemption expression referencing attributes whose runtime type differs from what the expression assumes (e.g. classification_level as string vs int64); expression uses functions on nil/absent values; cel-go upgrade changed runtime semantics of an extension function.","solutions":["Log/inspect the wrapped error to see the exact failing operation and attribute","Fix the stored exemption policy expression: use matches() or string() casts for type-sensitive comparisons and cel.bind/has() guards for absent values","Validate the expression at save time with ValidateMaskingRuleCELExpr-style compile+eval checks so bad expressions never reach evaluation","Pin or upgrade cel-go so extension function (ext.Strings) runtime behavior matches what the expression expects"],"exampleFix":"// before\nresource.classification_level == \"4\"\n// after\nstring(resource.classification_level) == \"4\"","handlingStrategy":"validation","validationCode":"// at save time: compile + sample eval\nprg, err := env.Program(ast)\nif err != nil { return err }\n_, _, err = prg.Eval(sampleAttributes) // catch runtime issues early\nreturn err","typeGuard":null,"tryCatchPattern":"pass, err := evaluateMaskingExemptionPolicyCondition(cond, attrs)\nif err != nil {\n\tlog.Printf(\"exemption condition %q failed eval: %v\", cond.GetExpression(), err)\n\treturn false, nil // deny exemption on error (fail-closed)\n}","preventionTips":["Validate policy expressions with a sample attribute set when admins save them","Use has() guards and explicit string()/int() casts around optional or any-typed attributes","Log the failing expression text with the wrapped error to speed triage","Test expressions against representative attribute values after cel-go upgrades"],"tags":["cel","runtime-eval","policy-engine","go"],"backgroundTag":"cel-expression-eval-failed","analyzedSha":"1870550677fe08f0d2a78c07acd27541464eb945","analyzedAt":"2026-09-06T21:16:13.665Z","contentChangedAt":"2026-09-06T21:16:13.665Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}