{"record":{"id":"9fbe6f8acb43076b","repo":"usememos/memos","slug":"unsupported-top-level-expression","errorCode":null,"errorMessage":"unsupported top-level expression","messagePattern":"unsupported top-level expression","errorType":"validation","errorClass":null,"httpStatus":400,"severity":"error","filePath":"internal/filter/parser.go","lineNumber":44,"sourceCode":"\t\t}\n\t\tif v, ok := val.(bool); ok {\n\t\t\treturn &ConstantCondition{Value: v}, nil\n\t\t}\n\t\treturn nil, errors.New(\"filter must evaluate to a boolean value\")\n\tcase *exprv1.Expr_IdentExpr:\n\t\tname := v.IdentExpr.GetName()\n\t\tfield, ok := pc.schema.Field(name)\n\t\tif !ok {\n\t\t\treturn nil, errors.Errorf(\"unknown identifier %q\", name)\n\t\t}\n\t\tif field.Type != FieldTypeBool {\n\t\t\treturn nil, errors.Errorf(\"identifier %q is not boolean\", name)\n\t\t}\n\t\treturn &FieldPredicateCondition{Field: name}, nil\n\tcase *exprv1.Expr_ComprehensionExpr:\n\t\treturn buildComprehensionCondition(v.ComprehensionExpr, pc.schema)\n\tdefault:\n\t\treturn nil, errors.New(\"unsupported top-level expression\")\n\t}\n}\n\nfunc buildCallCondition(call *exprv1.Expr_Call, pc parseContext) (Condition, error) {\n\tswitch call.Function {\n\tcase \"_&&_\":\n\t\tif len(call.Args) != 2 {\n\t\t\treturn nil, errors.New(\"logical AND expects two arguments\")\n\t\t}\n\t\tleft, err := buildCondition(call.Args[0], pc)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tright, err := buildCondition(call.Args[1], pc)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\treturn &LogicalCondition{","sourceCodeStart":26,"sourceCodeEnd":62,"githubUrl":"https://github.com/usememos/memos/blob/14d757ce1fb31c78590f374bc042f8dbedbc20d7/internal/filter/parser.go#L26-L62","documentation":"Returned by buildCondition's default branch when the top-level (or nested) AST node kind is a CallExpr, ConstExpr, IdentExpr, or Comprehension that was not matched — practically, an expression shape the condition builder does not translate. It marks the boundary of the supported CEL subset (logic ops, comparisons, in, text matches, comprehensions, boolean idents/constants).","triggerScenarios":"A filter whose root is a list/map literal, a ternary result of non-supported form, or any macro/expression kind outside the handled ExprKind cases. CEL's env may accept it syntactically while the Memos condition builder refuses to compile it to a Condition.","commonSituations":"Power users writing CEL beyond the supported subset (list literals, index expressions); filters written against a different CEL schema; engine version gaps after new syntax was allowed by env.Compile but not yet mapped in the parser.","solutions":["Rewrite the filter using supported constructs: field comparisons, &&/||/!, in, contains, and macro comprehensions.","Check the documented filter grammar/schema for the resource you are filtering.","Simplify to nested boolean comparisons of the same intent."],"exampleFix":"# before (unsupported shape)\n[tag in [\"a\",\"b\"] ? true : false]\n\n# after\ntag in [\"a\", \"b\"]","handlingStrategy":"validation","validationCode":"// Go — restrict input to the supported grammar before compiling\nvar allowed = regexp.MustCompile(`^[a-zA-Z0-9_.()\\s\\[\\]\",!=<>@&|!'-]+$`)\nif !allowed.MatchString(filter) {\n  return errors.New(\"filter uses unsupported syntax\")\n}\n_, err := engine.Compile(ctx, filter)","typeGuard":null,"tryCatchPattern":"if err != nil && strings.Contains(err.Error(), \"unsupported top-level expression\") {\n  return status.Errorf(codes.InvalidArgument, \"unsupported filter syntax; use comparisons, in, contains, and logical operators\")\n}","preventionTips":["Keep filters within the documented subset: comparisons, in, contains, &&/||/!, macros.","Provide an interactive filter tester in the UI with the engine's real errors.","Avoid pasting raw CEL from other systems without adapting to this schema."],"tags":["cel","filter","parser","unsupported","go"],"backgroundTag":null,"analyzedSha":"14d757ce1fb31c78590f374bc042f8dbedbc20d7","analyzedAt":"2026-08-15T09:27:36.538Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}