chenhg5/cc-connect · error

invalid delay or time %q (use duration like 2h30m, or ISO ti

Error message

invalid delay or time %q (use duration like 2h30m, or ISO time like 2026-05-15T14:00)

What it means

This is the final fallback error of ParseDelayOrTime: the input is non-empty, failed time.ParseDuration, and matched none of the supported ISO/local time layouts. The message quotes the offending input and states both accepted formats so the user can self-correct.

Source

Thrown at core/timer.go:488

		{time.RFC3339, false},
		{"2006-01-02T15:04:05", true},
		{"2006-01-02T15:04", true},
		{"2006-01-02 15:04:05", true},
		{"2006-01-02 15:04", true},
	}
	for _, l := range layouts {
		if l.local {
			if t, err := time.ParseInLocation(l.layout, s, time.Local); err == nil {
				return t, nil
			}
		} else {
			if t, err := time.Parse(l.layout, s); err == nil {
				return t, nil
			}
		}
	}

	return time.Time{}, fmt.Errorf("invalid delay or time %q (use duration like 2h30m, or ISO time like 2026-05-15T14:00)", s)
}

// FormatTimerRemaining returns a human-readable string for time remaining
// until the scheduled fire time.
func FormatTimerRemaining(scheduledAt time.Time) string {
	d := time.Until(scheduledAt)
	if d <= 0 {
		return "overdue"
	}
	if d < time.Minute {
		secs := int(d.Seconds() + 0.5) // round up for countdown display
		if secs >= 60 {
			return "1m"
		}
		return fmt.Sprintf("%ds", secs)
	}
	if d < time.Hour {
		mins := int(d.Minutes() + 0.5) // round up for countdown display

View on GitHub (pinned to 4000b2338a)

Solutions

  1. Use a Go duration string: '2h', '30m', '1h30m', '2h30m15s'.
  2. Use an ISO 8601 time like '2026-05-15T14:00' or with timezone '2026-05-15T14:00:00+08:00'.
  3. Translate natural-language or locale dates to one of the supported formats before calling (e.g. with a dateparse library or LLM preprocessing in the command handler).
  4. Check the error text: it echoes the rejected input in %q, confirming what was actually parsed.

Example fix

// before
at, err := core.ParseDelayOrTime("tomorrow 5pm")
// after
at, err := core.ParseDelayOrTime("24h") // or "2026-05-16T17:00"
Defensive patterns

Strategy: validation

Validate before calling

func looksLikeDelayOrTime(s string) bool {
    if _, err := time.ParseDuration(s); err == nil { return true }
    for _, layout := range []string{time.RFC3339, "2006-01-02T15:04", "2006-01-02T15:04:05"} {
        if _, err := time.Parse(layout, s); err == nil { return true }
    }
    return false
}

Try / catch

at, err := core.ParseDelayOrTime(arg)
if err != nil {
    reply(fmt.Sprintf("Could not understand %q. Use 2h30m or 2026-05-15T14:00.", arg))
    return
}

Prevention

When it happens

Trigger: Calling ParseDelayOrTime with a string that is neither a Go duration nor one of the supported time layouts, e.g. "tomorrow 5pm", "15/05/2026 14:00", "next monday", or an ISO date without time "2026-05-15".

Common situations: Users writing natural-language times ('in two hours', 'tonight'); locale-formatted dates (dd/mm/yyyy); missing seconds/timezone assumptions; passing a date-only string when a time is required.

Related errors


AI-assisted analysis of chenhg5/cc-connect@4000b2338a (2026-09-06). Data as JSON: /api/errors/7f3c7c3505a1bd96. Report an issue: GitHub.