{"record":{"id":"d091e9fdb5f9145b","repo":"bytebase/bytebase","slug":"failed-to-parse-expression","errorCode":null,"errorMessage":"failed to parse expression","messagePattern":"failed to parse expression","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"backend/api/v1/project_service.go","lineNumber":1267,"sourceCode":"// validateExpirationInExpression validates the IAM policy expression.\n// Currently only validate the following expression:\n// * request.time < timestamp(\"2021-01-01T00:00:00Z\")\n//\n// Other expressions will be ignored.\nfunc validateExpirationInExpression(expr string, maximumExpiration *durationpb.Duration) error {\n\tif maximumExpiration == nil {\n\t\treturn nil\n\t}\n\tif !strings.Contains(expr, \"request.time\") {\n\t\treturn errors.Errorf(\"request.time is required\")\n\t}\n\te, err := cel.NewEnv()\n\tif err != nil {\n\t\treturn errors.Wrap(err, \"failed to create cel environment\")\n\t}\n\tast, iss := e.Parse(expr)\n\tif iss != nil {\n\t\treturn errors.Wrap(iss.Err(), \"failed to parse expression\")\n\t}\n\n\tvar validator func(expr celast.Expr) error\n\n\tvalidator = func(expr celast.Expr) error {\n\t\tswitch expr.Kind() {\n\t\tcase celast.CallKind:\n\t\t\tfunctionName := expr.AsCall().FunctionName()\n\t\t\tswitch functionName {\n\t\t\tcase \"_||_\":\n\t\t\t\tfor _, arg := range expr.AsCall().Args() {\n\t\t\t\t\terr := validator(arg)\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\treturn err\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn nil\n\t\t\tcase \"_&&_\":","sourceCodeStart":1249,"sourceCodeEnd":1285,"githubUrl":"https://github.com/bytebase/bytebase/blob/1870550677fe08f0d2a78c07acd27541464eb945/backend/api/v1/project_service.go#L1249-L1285","documentation":"validateExpirationInExpression parses a CEL expression that encodes role expiration via request.time comparisons. This error wraps any failure from cel.Env.Parse(expr), meaning the expression string is not syntactically valid CEL (bad tokens, unbalanced parens, invalid operators). The library validates IAM policy expressions before accepting them, so malformed CEL is rejected up front.","triggerScenarios":"Calling buildIssueMessage or validateBindings with an IAM policy binding whose 'expression' field contains syntactically invalid CEL, e.g. 'timestamp(request.time) <' or 'request.time <\"2025-01-01T00:00:00Z' with unbalanced quotes/parens.","commonSituations":"Hand-edited IAM policy JSON, copy-pasted expressions with smart quotes or missing closing quotes, templates with unfilled placeholders like '<expiry-time>', or expressions built programmatically with formatting bugs.","solutions":["Validate the CEL expression locally with the CEL parser or an online CEL playground before submitting the policy","Check for unbalanced quotes, parentheses, and stray characters in the expression string","Use the exact expected form: timestamp(request.time) < timestamp(\"RFC3339-time\")","If generated, fix the code that interpolates the expiration timestamp into the expression template"],"exampleFix":"// before\nexpr := `timestamp(request.time) < timestamp(\"2026-01-01T00:00:00Z\"`  // missing )\n// after\nexpr := `timestamp(request.time) < timestamp(\"2026-01-01T00:00:00Z\")`","handlingStrategy":"validation","validationCode":"if _, iss := cel.NewEnv().Parse(expr); iss != nil { return fmt.Errorf(\"invalid CEL expression: %v\", iss.Err()) }","typeGuard":"func isNonEmptyString(s string) bool { return strings.TrimSpace(s) != \"\" }","tryCatchPattern":null,"preventionTips":["Lint CEL expressions with a shared parser before submission","Never hand-edit policy expressions; generate them from templates","Beware smart quotes from copy-paste"],"tags":["cel","validation","iam-policy","expression-parsing"],"backgroundTag":"invalid-argument-format","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"}