{"record":{"id":"7eadfc88d7a18864","repo":"bytebase/bytebase","slug":"only-name-and-email-support-q-operator-but-f","errorCode":null,"errorMessage":"only \"name\" and \"email\" support %q operator, but found %q","messagePattern":"only \"name\" and \"email\" support %q operator, but found %q","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"backend/store/account_filter.go","lineNumber":107,"sourceCode":"\t\t\t\t\tqq, err := getFilter(arg)\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\treturn nil, err\n\t\t\t\t\t}\n\t\t\t\t\tq.And(\"?\", qq)\n\t\t\t\t}\n\t\t\t\treturn qb.Q().Space(\"(?)\", q), nil\n\t\t\tcase celoperators.Equals:\n\t\t\t\tvariable, value := getVariableAndValueFromExpr(expr)\n\t\t\t\treturn parseToSQL(variable, value)\n\t\t\tcase celoverloads.Contains:\n\t\t\t\tvariable := expr.AsCall().Target().AsIdent()\n\t\t\t\targs := expr.AsCall().Args()\n\t\t\t\tif len(args) != 1 {\n\t\t\t\t\treturn nil, errors.Errorf(`invalid args for %q`, variable)\n\t\t\t\t}\n\t\t\t\tvalue := args[0].AsLiteral().Value()\n\t\t\t\tif variable != \"name\" && variable != \"email\" {\n\t\t\t\t\treturn nil, errors.Errorf(`only \"name\" and \"email\" support %q operator, but found %q`, celoverloads.Contains, variable)\n\t\t\t\t}\n\t\t\t\tstrValue, ok := value.(string)\n\t\t\t\tif !ok {\n\t\t\t\t\treturn nil, errors.Errorf(\"expect string, got %T, hint: filter literals should be string\", value)\n\t\t\t\t}\n\t\t\t\treturn qb.Q().Space(\"LOWER(\"+variable+\") LIKE ? ESCAPE '\\\\'\", containsPattern(strings.ToLower(strValue))), nil\n\t\t\tdefault:\n\t\t\t\treturn nil, errors.Errorf(\"unexpected function %v\", functionName)\n\t\t\t}\n\t\tdefault:\n\t\t\treturn nil, errors.Errorf(\"unexpected expr kind %v\", expr.Kind())\n\t\t}\n\t}\n\n\tq, err := getFilter(ast.NativeRep().Expr())\n\tif err != nil {\n\t\treturn nil, err\n\t}","sourceCodeStart":89,"sourceCodeEnd":125,"githubUrl":"https://github.com/bytebase/bytebase/blob/1870550677fe08f0d2a78c07acd27541464eb945/backend/store/account_filter.go#L89-L125","documentation":"The contains operator in the account filter is only implemented for the name and email columns; using it on any other variable (state, project, or an unsupported field) is rejected with this error. This is a deliberate whitelist, not a CEL limitation.","triggerScenarios":"Filters like `state.contains(\"ACT\")` or `project.contains(\"123\")` on the account list API.","commonSituations":"Assuming contains works uniformly across all filter fields (AIP-160 allows it broadly), or trying substring matching on state/project where only exact equality is supported.","solutions":["Restrict contains to name or email: `name.contains(\"x\")` / `email.contains(\"@corp\")`","Use exact equality for state and project: `state == \"ACTIVE\"`, `project == \"projects/123\"`","Implement additional contains support in account_filter.go if substring matching on other fields is genuinely needed"],"exampleFix":"// before\nfilter = \"state.contains(\\\"ACT\\\")\"\n// after\nfilter = \"state == \\\"ACTIVE\\\"\"","handlingStrategy":"validation","validationCode":"var containsAllowed = map[string]bool{\"name\":true,\"email\":true}\nif op == \"contains\" && !containsAllowed[field] {\n    return fmt.Errorf(\"contains only supported on name and email, not %q\", field)\n}","typeGuard":null,"tryCatchPattern":"if _, err := store.GetAccountListFilter(filter); err != nil {\n    return status.Errorf(codes.InvalidArgument, \"bad contains usage: %v\", err)\n}","preventionTips":["Apply contains only to name and email","Use == for state and project","Check the supported-operator whitelist before composing filters"],"tags":["cel","filter","unsupported-operator"],"backgroundTag":"unsupported-operation","analyzedSha":"1870550677fe08f0d2a78c07acd27541464eb945","analyzedAt":"2026-09-06T21:16:13.665Z","contentChangedAt":"2026-09-06T21:16:13.665Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}