{"record":{"id":"401e24bf6ed84ca7","repo":"gastownhall/beads","slug":"invalid-updated-time-w","errorCode":null,"errorMessage":"invalid updated time: %w","messagePattern":"invalid updated time: %w","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/query/evaluator.go","lineNumber":362,"sourceCode":"\tcase OpGreater:\n\t\tfilter.CreatedAfter = &t\n\tcase OpGreaterEq:\n\t\tfilter.CreatedAfter = &t\n\tcase OpLess:\n\t\tfilter.CreatedBefore = &t\n\tcase OpLessEq:\n\t\tendOfDay := time.Date(t.Year(), t.Month(), t.Day(), 23, 59, 59, 999999999, t.Location())\n\t\tfilter.CreatedBefore = &endOfDay\n\tdefault:\n\t\treturn fmt.Errorf(\"created does not support %s operator\", comp.Op.String())\n\t}\n\treturn nil\n}\n\nfunc (e *Evaluator) applyUpdatedFilter(comp *ComparisonNode, filter *types.IssueFilter) error {\n\tt, err := e.parseTimeValue(comp)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"invalid updated time: %w\", err)\n\t}\n\tswitch comp.Op {\n\tcase OpEquals:\n\t\tdayStart := time.Date(t.Year(), t.Month(), t.Day(), 0, 0, 0, 0, t.Location())\n\t\tdayEnd := dayStart.Add(24 * time.Hour)\n\t\tfilter.UpdatedAfter = &dayStart\n\t\tfilter.UpdatedBefore = &dayEnd\n\tcase OpGreater:\n\t\tfilter.UpdatedAfter = &t\n\tcase OpGreaterEq:\n\t\tfilter.UpdatedAfter = &t\n\tcase OpLess:\n\t\tfilter.UpdatedBefore = &t\n\tcase OpLessEq:\n\t\tendOfDay := time.Date(t.Year(), t.Month(), t.Day(), 23, 59, 59, 999999999, t.Location())\n\t\tfilter.UpdatedBefore = &endOfDay\n\tdefault:\n\t\treturn fmt.Errorf(\"updated does not support %s operator\", comp.Op.String())","sourceCodeStart":344,"sourceCodeEnd":380,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/query/evaluator.go#L344-L380","documentation":"Same shape as the created parse error but for the updated field: parseTimeValue failed while resolving the value of an `updated` comparison into a time.Time. Supported inputs are duration tokens (7d, 24h → now minus duration) and the formats accepted by timeparsing.ParseRelativeTime; the original parse error is wrapped with %w.","triggerScenarios":"Queries like `updated > 3w2`, `updated = `, `updated < last fridayish` — any value the time parser rejects after the `updated` field.","commonSituations":"Stale scripts with hand-built date strings; timezone-offset values the parser does not accept; mixing units the duration parser rejects (e.g. `1w3d` if unsupported); empty values from template interpolation.","solutions":["Use a compact relative duration: `updated > 7d` or `updated < 24h`","Use an absolute timestamp ParseRelativeTime accepts (e.g. `2026-08-30` or RFC3339)","Inspect the wrapped cause (%w) for the precise parsing failure and adjust the value"],"exampleFix":"// before\nbd ready --query 'updated > 30 days'\n// after\nbd ready --query 'updated > 30d'","handlingStrategy":"validation","validationCode":"// Validate the updated value parses before running the query\nfunc validUpdatedValue(v string) bool {\n\tif regexp.MustCompile(`^\\d+[dhmsw]$`).MatchString(v) {\n\t\treturn true\n\t}\n\t_, err := timeparsing.ParseRelativeTime(v, time.Now())\n\treturn err == nil\n}\nif !validUpdatedValue(value) { return fmt.Errorf(\"bad updated value: %q\", value) }","typeGuard":"func isParseableTime(v string) bool {\n\t_, err := timeparsing.ParseRelativeTime(v, time.Now())\n\treturn err == nil\n}","tryCatchPattern":"if err := eval.Eval(node); err != nil {\n\tif strings.Contains(err.Error(), \"invalid updated time\") {\n\t\t// fix the duration/date value (e.g. '30 days' -> '30d') and retry\n\t}\n}","preventionTips":["Use duration shorthand: 30d, 12h — not '30 days'","Use ISO/RFC3339 timestamps for absolute values","Sanitize interpolated variables so empty strings never reach the parser","Test parseTimeValue on all date inputs your tooling generates"],"tags":["query","time-parsing","updated","invalid-input"],"backgroundTag":"invalid-date-format","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}