gohugoio/hugo · error

%q is not a valid duration unit

Error message

%q is not a valid duration unit

What it means

Hugo's `time.Duration` template function (alias `duration`) converts a number into a Go time.Duration using a unit name looked up in a fixed map (durationUnits in tpl/time/time.go). If the unit string passed as the first argument isn't one of the supported keys, the lookup fails and this error is returned. Only nanosecond/ns, microsecond/us/µs, millisecond/ms, second/s, minute/m, and hour/h are accepted.

Source

Thrown at tpl/time/time.go:143

	"ms":          time.Millisecond,
	"second":      time.Second,
	"s":           time.Second,
	"minute":      time.Minute,
	"m":           time.Minute,
	"hour":        time.Hour,
	"h":           time.Hour,
}

// Duration converts the given number to a time.Duration.
// Unit is one of nanosecond/ns, microsecond/us/µs, millisecond/ms, second/s, minute/m or hour/h.
func (ns *Namespace) Duration(unit any, number any) (time.Duration, error) {
	unitStr, err := cast.ToStringE(unit)
	if err != nil {
		return 0, err
	}
	unitDuration, found := durationUnits[unitStr]
	if !found {
		return 0, fmt.Errorf("%q is not a valid duration unit", unit)
	}
	n, err := cast.ToInt64E(number)
	if err != nil {
		return 0, err
	}
	return time.Duration(n) * unitDuration, nil
}

View on GitHub ↗ (pinned to 8a468df065)

Solutions

  1. Use an exact supported unit: nanosecond/ns, microsecond/us, millisecond/ms, second/s, minute/m, hour/h — singular, lowercase.
  2. For days or weeks, multiply hours: `{{ duration "hour" (mul 24 7) }}`.
  3. Check argument order: unit comes first, number second (`duration "second" 60`).

Example fix

<!-- before -->
{{ duration "minutes" 5 }}
<!-- after -->
{{ duration "minute" 5 }}
Defensive patterns

Strategy: validation

Validate before calling

{{ $unit := "days" }}
{{ $valid := slice "nanosecond" "microsecond" "millisecond" "second" "minute" "hour" }}
{{ if in $valid $unit }}{{ time.Duration $unit 3 }}{{ end }}

Try / catch

{{ with try (time.Duration $unit $n) }}{{ if .Err }}{{ warnf "bad duration unit: %s" .Err }}{{ else }}{{ .Value }}{{ end }}{{ end }}

Prevention

When it happens

Trigger: Calling `{{ duration "seconds" 60 }}` or `{{ time.Duration "days" 2 }}` in a template — any unit string not exactly matching a durationUnits key, including plural forms ("minutes", "hours"), capitalized forms ("Second"), or unsupported units ("day", "week", "d").

Common situations: Developers writing cache-busting or scheduling logic in templates who assume plural units work (`duration "minutes" 5`); trying to express days or weeks, which Go's time.Duration units don't include; passing the number and unit in swapped order so the number becomes the unit string.

Related errors


AI-assisted analysis of gohugoio/hugo@8a468df065 (2026-07-31). Data as JSON: /data/errors/d384f635c32c96c7.json. Report an issue: GitHub ↗.