usememos/memos · error
matches expects exactly one argument
Error message
matches expects exactly one argument
What it means
The regex matches() translation accepts exactly one argument (the pattern). A call with zero or 2+ arguments cannot be compiled to a single SQL regex predicate, so buildMatchesCondition rejects it at parse time.
Source
Thrown at internal/filter/parser.go:362
func buildMatchesCondition(call *exprv1.Expr_Call, schema Schema) (Condition, error) {
if call.Target == nil {
return nil, errors.New("matches requires a target")
}
targetName, err := getIdentName(call.Target)
if err != nil {
return nil, err
}
field, ok := schema.Field(targetName)
if !ok {
return nil, errors.Errorf("unknown identifier %q", targetName)
}
if !field.SupportsContains {
return nil, errors.Errorf("identifier %q does not support matches()", targetName)
}
if len(call.Args) != 1 {
return nil, errors.New("matches expects exactly one argument")
}
value, err := getConstValue(call.Args[0])
if err != nil {
return nil, errors.Wrap(err, "matches only supports literal arguments")
}
pattern, ok := value.(string)
if !ok {
return nil, errors.New("matches argument must be a string")
}
return &RegexCondition{
Field: targetName,
Pattern: pattern,
}, nil
}
func buildValueExpr(expr *exprv1.Expr, pc parseContext) (ValueExpr, error) {
if identName, err := getIdentName(expr); err == nil {
// `now` is not a schema field; it folds to the frozen evaluation time.View on GitHub (pinned to 14d757ce1f)
Solutions
- Pass exactly one regex pattern: content.matches("^TODO.*")
- Drop any flags argument; use inline (?i) in the pattern for case-insensitive matching if supported by the store's regex dialect
- Lint user-supplied filters with a CEL parser before calling the API
Example fix
// before
content.matches("todo", "i")
// after
content.matches("(?i)todo") Defensive patterns
Strategy: validation
Validate before calling
// Go: quick arity lint for matches re := regexp.MustCompile(`\.matches\((?:[^"()]|"[^"]*")*\)`) // full validation is easier via cel.Parse + an Ast walker asserting len(args)==1
Prevention
- Pass one pattern string per matches() call
- Use inline flags like (?i) instead of a second argument
- Dry-run compile filters in CI for template-generated expressions
When it happens
Trigger: content.matches() or content.matches("a", "b") in a filter expression passed to the memo filter API.
Common situations: Copy-paste from JS RegExp(text, flags) style where flags are a second argument; hand-written filters missing the pattern string.
Related errors
- matches requires a target
- matches argument must be a string
- size() expects one argument
- timestamp() expects one argument
- duration() expects one argument
AI-assisted analysis of usememos/memos@14d757ce1f (2026-08-15).
Data as JSON: /api/errors/298be120adc9fc14.
Report an issue: GitHub.