{"record":{"id":"1fc821e947042178","repo":"usememos/memos","slug":"logical-not-expects-one-argument","errorCode":null,"errorMessage":"logical NOT expects one argument","messagePattern":"logical NOT expects one argument","errorType":"validation","errorClass":null,"httpStatus":400,"severity":"error","filePath":"internal/filter/parser.go","lineNumber":86,"sourceCode":"\t\tif len(call.Args) != 2 {\n\t\t\treturn nil, errors.New(\"logical OR 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{\n\t\t\tOperator: LogicalOr,\n\t\t\tLeft:     left,\n\t\t\tRight:    right,\n\t\t}, nil\n\tcase \"!_\":\n\t\tif len(call.Args) != 1 {\n\t\t\treturn nil, errors.New(\"logical NOT expects one argument\")\n\t\t}\n\t\tchild, err := buildCondition(call.Args[0], pc)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\treturn &NotCondition{Expr: child}, nil\n\tcase \"_==_\", \"_!=_\", \"_<_\", \"_>_\", \"_<=_\", \"_>=_\":\n\t\treturn buildComparisonCondition(call, pc)\n\tcase \"@in\":\n\t\treturn buildInCondition(call, pc)\n\tcase \"contains\":\n\t\treturn buildTextMatchCondition(call, pc.schema, TextMatchContains)\n\tcase \"startsWith\":\n\t\treturn buildTextMatchCondition(call, pc.schema, TextMatchPrefix)\n\tcase \"endsWith\":\n\t\treturn buildTextMatchCondition(call, pc.schema, TextMatchSuffix)\n\tcase \"matches\":\n\t\treturn buildMatchesCondition(call, pc.schema)","sourceCodeStart":68,"sourceCodeEnd":104,"githubUrl":"https://github.com/usememos/memos/blob/14d757ce1fb31c78590f374bc042f8dbedbc20d7/internal/filter/parser.go#L68-L104","documentation":"Returned by buildCallCondition for the \"!_\" (logical NOT) function when the call does not have exactly 1 argument. Unary ! always carries one arg in normal CEL, so this is an internal/programmatic-AST invariant failure rather than a typical user mistake.","triggerScenarios":"An Expr_Call tagged !_ with arity != 1 — essentially only possible with hand-built ASTs or a malformed macro expansion, not from parsing a user string.","commonSituations":"Programmatic filter construction; testing the parser with synthetic ASTs.","solutions":["Use plain unary negation in the filter text: !pinned.","When building ASTs, emit !_ with exactly one argument.","Treat occurrence from a normal filter string as an engine bug and report it."],"exampleFix":"# before (synthetic AST misuse)\n\n# after (plain filter)\n!pinned","handlingStrategy":"validation","validationCode":"// Go — emit plain unary NOT when generating\nfunc not(e string) string { return fmt.Sprintf(\"!(%s)\", e) }","typeGuard":null,"tryCatchPattern":"if err != nil && strings.Contains(err.Error(), \"logical NOT expects one argument\") {\n  return errors.Wrap(err, \"internal filter AST inconsistency; report with the filter text\")\n}","preventionTips":["Use textbook !expr syntax in filters.","When building ASTs programmatically, assert !_ arity is 1 before submitting.","Add parser unit tests for every operator arity you emit."],"tags":["cel","filter","parser","logical-not","go"],"backgroundTag":null,"analyzedSha":"14d757ce1fb31c78590f374bc042f8dbedbc20d7","analyzedAt":"2026-08-15T09:27:36.538Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}