usememos/memos · error
logical NOT expects one argument
Error message
logical NOT expects one argument
What it means
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.
Source
Thrown at internal/filter/parser.go:86
if len(call.Args) != 2 {
return nil, errors.New("logical OR expects two arguments")
}
left, err := buildCondition(call.Args[0], pc)
if err != nil {
return nil, err
}
right, err := buildCondition(call.Args[1], pc)
if err != nil {
return nil, err
}
return &LogicalCondition{
Operator: LogicalOr,
Left: left,
Right: right,
}, nil
case "!_":
if len(call.Args) != 1 {
return nil, errors.New("logical NOT expects one argument")
}
child, err := buildCondition(call.Args[0], pc)
if err != nil {
return nil, err
}
return &NotCondition{Expr: child}, nil
case "_==_", "_!=_", "_<_", "_>_", "_<=_", "_>=_":
return buildComparisonCondition(call, pc)
case "@in":
return buildInCondition(call, pc)
case "contains":
return buildTextMatchCondition(call, pc.schema, TextMatchContains)
case "startsWith":
return buildTextMatchCondition(call, pc.schema, TextMatchPrefix)
case "endsWith":
return buildTextMatchCondition(call, pc.schema, TextMatchSuffix)
case "matches":
return buildMatchesCondition(call, pc.schema)View on GitHub (pinned to 14d757ce1f)
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.
Example fix
# before (synthetic AST misuse) # after (plain filter) !pinned
Defensive patterns
Strategy: validation
Validate before calling
// Go — emit plain unary NOT when generating
func not(e string) string { return fmt.Sprintf("!(%s)", e) } Try / catch
if err != nil && strings.Contains(err.Error(), "logical NOT expects one argument") {
return errors.Wrap(err, "internal filter AST inconsistency; report with the filter text")
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: Programmatic filter construction; testing the parser with synthetic ASTs.
Related errors
- filter must evaluate to a boolean value
- unsupported top-level expression
- logical AND expects two arguments
- logical OR expects two arguments
- comparison expects two arguments
AI-assisted analysis of usememos/memos@14d757ce1f (2026-08-15).
Data as JSON: /api/errors/1fc821e947042178.
Report an issue: GitHub.