gastownhall/beads · error

invalid updated time: %w

Error message

invalid updated time: %w

What it means

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.

Source

Thrown at internal/query/evaluator.go:362

	case OpGreater:
		filter.CreatedAfter = &t
	case OpGreaterEq:
		filter.CreatedAfter = &t
	case OpLess:
		filter.CreatedBefore = &t
	case OpLessEq:
		endOfDay := time.Date(t.Year(), t.Month(), t.Day(), 23, 59, 59, 999999999, t.Location())
		filter.CreatedBefore = &endOfDay
	default:
		return fmt.Errorf("created does not support %s operator", comp.Op.String())
	}
	return nil
}

func (e *Evaluator) applyUpdatedFilter(comp *ComparisonNode, filter *types.IssueFilter) error {
	t, err := e.parseTimeValue(comp)
	if err != nil {
		return fmt.Errorf("invalid updated time: %w", err)
	}
	switch comp.Op {
	case OpEquals:
		dayStart := time.Date(t.Year(), t.Month(), t.Day(), 0, 0, 0, 0, t.Location())
		dayEnd := dayStart.Add(24 * time.Hour)
		filter.UpdatedAfter = &dayStart
		filter.UpdatedBefore = &dayEnd
	case OpGreater:
		filter.UpdatedAfter = &t
	case OpGreaterEq:
		filter.UpdatedAfter = &t
	case OpLess:
		filter.UpdatedBefore = &t
	case OpLessEq:
		endOfDay := time.Date(t.Year(), t.Month(), t.Day(), 23, 59, 59, 999999999, t.Location())
		filter.UpdatedBefore = &endOfDay
	default:
		return fmt.Errorf("updated does not support %s operator", comp.Op.String())

View on GitHub (pinned to 71377f2769)

Solutions

  1. Use a compact relative duration: `updated > 7d` or `updated < 24h`
  2. Use an absolute timestamp ParseRelativeTime accepts (e.g. `2026-08-30` or RFC3339)
  3. Inspect the wrapped cause (%w) for the precise parsing failure and adjust the value

Example fix

// before
bd ready --query 'updated > 30 days'
// after
bd ready --query 'updated > 30d'
Defensive patterns

Strategy: validation

Validate before calling

// Validate the updated value parses before running the query
func validUpdatedValue(v string) bool {
	if regexp.MustCompile(`^\d+[dhmsw]$`).MatchString(v) {
		return true
	}
	_, err := timeparsing.ParseRelativeTime(v, time.Now())
	return err == nil
}
if !validUpdatedValue(value) { return fmt.Errorf("bad updated value: %q", value) }

Type guard

func isParseableTime(v string) bool {
	_, err := timeparsing.ParseRelativeTime(v, time.Now())
	return err == nil
}

Try / catch

if err := eval.Eval(node); err != nil {
	if strings.Contains(err.Error(), "invalid updated time") {
		// fix the duration/date value (e.g. '30 days' -> '30d') and retry
	}
}

Prevention

When it happens

Trigger: Queries like `updated > 3w2`, `updated = `, `updated < last fridayish` — any value the time parser rejects after the `updated` field.

Common situations: 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.

Related errors


AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30). Data as JSON: /api/errors/401e24bf6ed84ca7. Report an issue: GitHub.