usememos/memos · error
text match requires a target
Error message
text match requires a target
What it means
Returned by buildTextMatchCondition (internal/filter/parser.go) for contains (and other text-match functions) when call.Target is nil — i.e., the function was invoked as a plain call, not as a receiver-style method call. Text matching is only supported in member syntax (field.contains("x")), where the receiver becomes the target field.
Source
Thrown at internal/filter/parser.go:313
if _, ok := pc.schema.Field(identName); !ok {
return nil, errors.Errorf("unknown identifier %q", identName)
}
element, err := buildValueExpr(call.Args[0], pc)
if err != nil {
return nil, err
}
return &ElementInCondition{
Element: element,
Field: identName,
}, nil
}
return nil, errors.New("invalid use of in operator")
}
func buildTextMatchCondition(call *exprv1.Expr_Call, schema Schema, mode TextMatchMode) (Condition, error) {
if call.Target == nil {
return nil, errors.New("text match 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 text matching", targetName)
}
if len(call.Args) != 1 {
return nil, errors.New("text match expects exactly one argument")
}
value, err := getConstValue(call.Args[0])
if err != nil {View on GitHub (pinned to 14d757ce1f)
Solutions
- Use receiver syntax: content.contains("hello").
- Confirm the field supports text matching (SupportsContains) — e.g., content-like fields, not enums.
- When generating filters, emit member-call syntax for contains.
Example fix
# before
contains(content, "hello")
# after
content.contains("hello") Defensive patterns
Strategy: validation
Validate before calling
// Go/TS — lint saved filters for function-style text matching before compile
var badContains = regexp.MustCompile(`(?m)(^|[^.\w])contains\s*\(`)
if badContains.MatchString(filter) {
return errors.New("use member syntax: field.contains(\"value\")")
}
_, err := engine.Compile(ctx, filter) Try / catch
if err != nil && strings.Contains(err.Error(), "text match requires a target") {
return status.Errorf(codes.InvalidArgument, "write text matching as field.contains(\"value\")")
} Prevention
- Teach receiver syntax in filter docs/examples: content.contains("x").
- Offer filter templates with correct member-call syntax in the UI.
- Validate at save time and show the engine's message next to the editor.
When it happens
Trigger: Writing contains(content, "x") instead of content.contains("x"); any filter invoking the text-match function without a member target so the parser has no field to bind the match to.
Common situations: Users familiar with function-call syntax migrating from other query languages; generated filters calling contains as a global function.
Related errors
- filter must evaluate to a boolean value
- unsupported top-level expression
- logical AND expects two arguments
- logical OR expects two arguments
- logical NOT expects one argument
AI-assisted analysis of usememos/memos@14d757ce1f (2026-08-15).
Data as JSON: /api/errors/4d053de82b24f988.
Report an issue: GitHub.