usememos/memos · error
duration() argument must be a string
Error message
duration() argument must be a string
What it means
After checking arity and literalness, evaluateDuration requires the literal to be a string parseable by Go's time.ParseDuration. A non-string literal (number or boolean) reaches the type assertion failure and the filter is rejected.
Source
Thrown at internal/filter/parser.go:624
case int64:
return v, true, nil
default:
return 0, false, errors.New("timestamp() argument must be an RFC3339 string or epoch int")
}
}
// evaluateDuration folds duration("<go-duration>") into a number of seconds.
func evaluateDuration(call *exprv1.Expr_Call) (int64, bool, error) {
if len(call.Args) != 1 {
return 0, false, errors.New("duration() expects one argument")
}
value, err := getConstValue(call.Args[0])
if err != nil {
return 0, false, errors.Wrap(err, "duration() only supports literal arguments")
}
str, ok := value.(string)
if !ok {
return 0, false, errors.New("duration() argument must be a string")
}
d, err := time.ParseDuration(str)
if err != nil {
return 0, false, errors.Wrap(err, "invalid duration literal")
}
return int64(d.Seconds()), true, nil
}
// timestampAccessors is the set of supported CEL timestamp accessor methods.
var timestampAccessors = map[string]bool{
"getFullYear": true,
"getMonth": true,
"getDate": true,
"getDayOfMonth": true,
"getDayOfWeek": true,
"getDayOfYear": true,
"getHours": true,
"getMinutes": true,View on GitHub (pinned to 14d757ce1f)
Solutions
- Quote a Go duration string: duration("24h")
- Use arithmetic on seconds only after conversion: now - duration("24h") stays one call
- For raw second math, compare against now - 86400 directly since now folds to epoch seconds
Example fix
// before
created_ts > now - duration(86400)
// after
created_ts > now - duration("24h") Defensive patterns
Strategy: type-guard
Validate before calling
// TS: only allow quoted duration strings into the filter
const build = (d: string) => `now - duration(${JSON.stringify(d)})`;
if (typeof d !== 'string') throw new TypeError('duration must be a string like "24h"'); Type guard
const isDurationString = (v: unknown): v is string => typeof v === 'string' && /^\d+(ns|us|µs|ms|s|m|h)+$/.test(v);
Prevention
- Always quote duration arguments; the DSL takes strings, not numbers
- For raw second arithmetic, subtract integers from now directly
- Validate with time.ParseDuration equivalents in client code
When it happens
Trigger: duration(24), duration(86400), or duration(true) — passing a bare number where a quoted Go duration string is required.
Common situations: Assuming duration() takes seconds as an integer; converting from another DSL where durations are numeric.
Related errors
- text match argument must be a string
- matches argument must be a string
- timestamp() argument must be an RFC3339 string or epoch int
- duration() expects one argument
- set operations require string elements
AI-assisted analysis of usememos/memos@14d757ce1f (2026-08-15).
Data as JSON: /api/errors/cc527f7433dbeba8.
Report an issue: GitHub.