{"record":{"id":"879e7f5bc285ab2a","repo":"usememos/memos","slug":"duration-expects-one-argument","errorCode":null,"errorMessage":"duration() expects one argument","messagePattern":"duration\\(\\) expects one argument","errorType":"validation","errorClass":null,"httpStatus":400,"severity":"error","filePath":"internal/filter/parser.go","lineNumber":616,"sourceCode":"\t}\n\tswitch v := value.(type) {\n\tcase string:\n\t\tts, err := time.Parse(time.RFC3339, v)\n\t\tif err != nil {\n\t\t\treturn 0, false, errors.Wrap(err, \"invalid timestamp literal\")\n\t\t}\n\t\treturn ts.Unix(), true, nil\n\tcase int64:\n\t\treturn v, true, nil\n\tdefault:\n\t\treturn 0, false, errors.New(\"timestamp() argument must be an RFC3339 string or epoch int\")\n\t}\n}\n\n// evaluateDuration folds duration(\"<go-duration>\") into a number of seconds.\nfunc evaluateDuration(call *exprv1.Expr_Call) (int64, bool, error) {\n\tif len(call.Args) != 1 {\n\t\treturn 0, false, errors.New(\"duration() expects one argument\")\n\t}\n\tvalue, err := getConstValue(call.Args[0])\n\tif err != nil {\n\t\treturn 0, false, errors.Wrap(err, \"duration() only supports literal arguments\")\n\t}\n\tstr, ok := value.(string)\n\tif !ok {\n\t\treturn 0, false, errors.New(\"duration() argument must be a string\")\n\t}\n\td, err := time.ParseDuration(str)\n\tif err != nil {\n\t\treturn 0, false, errors.Wrap(err, \"invalid duration literal\")\n\t}\n\treturn int64(d.Seconds()), true, nil\n}\n\n// timestampAccessors is the set of supported CEL timestamp accessor methods.\nvar timestampAccessors = map[string]bool{","sourceCodeStart":598,"sourceCodeEnd":634,"githubUrl":"https://github.com/usememos/memos/blob/14d757ce1fb31c78590f374bc042f8dbedbc20d7/internal/filter/parser.go#L598-L634","documentation":"evaluateDuration folds duration(\"<go-duration>\") into an integer number of seconds, enabling expressions like created_ts > now - duration(\"24h\"). It first requires exactly one argument; zero or multiple arguments fail here.","triggerScenarios":"Filters like created_ts > now - duration() or duration(\"24h\", \"1h\") — any duration() call whose argument count is not 1.","commonSituations":"Trying to sum multiple durations as separate arguments instead of adding them; template variable that expands empty for the duration string.","solutions":["Pass one Go duration string: duration(\"24h\")","Combine spans inside the string: duration(\"1h30m\")","Add two duration() calls with + if needed"],"exampleFix":"// before\nnow - duration(\"24h\", \"30m\")\n\n// after\nnow - duration(\"24h30m\")","handlingStrategy":"validation","validationCode":"// Go: validate a Go duration string before templating\nif _, err := time.ParseDuration(d); err != nil {\n    return errors.Wrap(err, \"invalid duration\")\n}","typeGuard":"func isGoDuration(s string) bool { _, err := time.ParseDuration(s); return err == nil }","tryCatchPattern":null,"preventionTips":["Pass one quoted Go duration string: duration(\"24h\")","Combine spans inside the string (\"1h30m\") or sum separate duration() calls","Validate duration inputs with time.ParseDuration before building filters"],"tags":["cel","duration","arity","filter"],"backgroundTag":null,"analyzedSha":"14d757ce1fb31c78590f374bc042f8dbedbc20d7","analyzedAt":"2026-08-15T09:27:36.538Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}