{"record":{"id":"10a089afb2148125","repo":"usememos/memos","slug":"unsupported-value-expression","errorCode":null,"errorMessage":"unsupported value expression","messagePattern":"unsupported value expression","errorType":"validation","errorClass":null,"httpStatus":400,"severity":"error","filePath":"internal/filter/parser.go","lineNumber":436,"sourceCode":"\t\t\t}\n\t\t\treturn &FunctionValue{\n\t\t\t\tName: \"size\",\n\t\t\t\tArgs: []ValueExpr{arg},\n\t\t\t}, nil\n\t\tcase \"_+_\", \"_-_\", \"_*_\":\n\t\t\tvalue, ok, err := evaluateNumeric(expr, pc.now)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tif ok {\n\t\t\t\treturn &LiteralValue{Value: value}, nil\n\t\t\t}\n\t\tdefault:\n\t\t\t// Fall through to error return below\n\t\t}\n\t}\n\n\treturn nil, errors.New(\"unsupported value expression\")\n}\n\nfunc toComparisonOperator(fn string) (ComparisonOperator, error) {\n\tswitch fn {\n\tcase \"_==_\":\n\t\treturn CompareEq, nil\n\tcase \"_!=_\":\n\t\treturn CompareNeq, nil\n\tcase \"_<_\":\n\t\treturn CompareLt, nil\n\tcase \"_>_\":\n\t\treturn CompareGt, nil\n\tcase \"_<=_\":\n\t\treturn CompareLte, nil\n\tcase \"_>=_\":\n\t\treturn CompareGte, nil\n\tdefault:\n\t\treturn \"\", errors.Errorf(\"unsupported comparison operator %q\", fn)","sourceCodeStart":418,"sourceCodeEnd":454,"githubUrl":"https://github.com/usememos/memos/blob/14d757ce1fb31c78590f374bc042f8dbedbc20d7/internal/filter/parser.go#L418-L454","documentation":"buildValueExpr is the fallback path for the right-hand side of comparisons: it accepts identifiers (field refs and now), literals, timestamp accessors, size(), and constant-foldable arithmetic. Anything else — a function call, a list, a select expression — falls through to this terminal 'unsupported value expression' error.","triggerScenarios":"Comparisons whose value side uses an unsupported construct: visibility in [\"PUBLIC\", \"SHARED\"] as a raw list without in, created_ts == created_ts + 1 (non-constant arithmetic), or calling an unknown function inside a comparison.","commonSituations":"Writing CEL that is valid syntax but outside the supported subset — e.g. string concatenation on the right side, ternaries, or custom functions; the filter DSL deliberately supports only a small expression whitelist.","solutions":["Reduce the value side to a literal, field identifier, now, timestamp()/duration() arithmetic, or size()","Use the in operator with a list literal for membership tests instead of comparing against a list","Precompute dynamic values in your code and inline the resulting literal"],"exampleFix":"// before\nvisibility in [\"PUBLIC\"] && content == \"a\" + \"b\"\n\n// after\nvisibility in [\"PUBLIC\"] && content == \"ab\"","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  const conditions = compileFilter(filter);\n} catch (e) {\n  if (String(e).includes('unsupported value expression')) {\n    // simplify: right side of comparisons must be literal / field / now / timestamp()/duration() math / size()\n    return simplifyFilter(filter);\n  }\n  throw e;\n}","preventionTips":["Keep comparison right-hand sides to literals, field refs, now, or foldable arithmetic","Use in with list literals for membership instead of list equality","Precompute dynamic values in application code and inline the results"],"tags":["cel","filter","unsupported-expression","parser"],"backgroundTag":null,"analyzedSha":"14d757ce1fb31c78590f374bc042f8dbedbc20d7","analyzedAt":"2026-08-15T09:27:36.538Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}