usememos/memos · error
InvalidArgument
InvalidArgument
Error message
filter cannot be empty
What it means
validateFilter is used by memo-view APIs (e.g. CreateMemoView) to check a user-supplied CEL filter string before persisting it. An empty string is rejected immediately with InvalidArgument; non-empty strings are compiled with the store dialect to catch syntax errors early. The empty check exists because compiling '' would produce a confusing downstream error.
Source
Thrown at server/router/api/v1/memo_view_service.go:226
}
if err := s.authorizeMemoViewAccess(ctx, user); err != nil {
return nil, err
}
found, err := s.Store.RemoveUserMemoView(ctx, user.ID, memoViewID)
if err != nil {
return nil, status.Errorf(codes.Internal, "failed to delete memo view: %v", err)
}
if !found {
return nil, status.Errorf(codes.NotFound, "memo view not found")
}
return &emptypb.Empty{}, nil
}
func (s *APIV1Service) validateFilter(ctx context.Context, filterStr string) error {
if filterStr == "" {
return errors.New("filter cannot be empty")
}
engine, err := filter.DefaultEngine()
if err != nil {
return err
}
if _, err := engine.CompileToStatement(ctx, filterStr, filter.RenderOptions{Dialect: s.filterDialect()}); err != nil {
return errors.Wrap(err, "failed to compile filter")
}
return nil
}
// filterDialect maps the configured database driver onto the filter engine dialect.
func (s *APIV1Service) filterDialect() filter.DialectName {
switch s.Profile.Driver {
case "mysql":
return filter.DialectMySQLView on GitHub (pinned to 14d757ce1f)
Solutions
- Require a non-empty filter in the view form before enabling save.
- For a catch-all view, use a trivially true CEL expression appropriate to the schema (e.g. 'true' if supported by the compiler) instead of ''.
- Test the filter string compiles before persisting (the endpoint does this for you; fail early client-side for better UX).
Example fix
// before
await viewClient.createMemoView({ view: { filter: filterExpr } }); // filterExpr = ''
// after
if (!filterExpr.trim()) throw new Error('Filter is required');
await viewClient.createMemoView({ view: { filter: filterExpr } }); Defensive patterns
Strategy: validation
Validate before calling
if (!filterStr.trim()) throw new Error('Filter cannot be empty');
// optionally pre-compile client-side with a CEL library for faster feedback Prevention
- Disable the save/create button until the filter builder has produced a non-empty expression.
- Never map 'no conditions selected' to '' — decide between omitting the view and an explicit match-all.
- Surface the server's compile error text to users; it names the CEL syntax problem.
When it happens
Trigger: CreateMemoView / UpdateMemoView with filter = '' ; a view-creation form where the filter builder returned an empty string; programmatically creating a 'catch-all' view with no conditions.
Common situations: Filter editor cleared by the user but the request still sent; conditional filter construction (cond ? expr : '') leaking empty strings; clients assuming empty filter means 'match everything'.
Related errors
AI-assisted analysis of usememos/memos@14d757ce1f (2026-08-15).
Data as JSON: /api/errors/a7ed13f1d7a44e97.
Report an issue: GitHub.