gohugoio/hugo · error

cannot convert to time.Duration

Error message

cannot convert %v to time.Duration

What it means

Returned by types.ToDurationE when neither the integer-fast-path (cast.ToInt > 0) nor time.ParseDuration succeeds. ToDuration treats positive integers as milliseconds; everything else must be a Go duration string like '30s', '5m', '2h45m'.

Solutions

  1. Use Go duration syntax: '30s', '5m', '2h'.
  2. For millisecond counts, pass a plain integer (e.g. 500 → 500ms).
  3. Validate the field against time.ParseDuration in a config lint step.

Example fix

// before
timeout: "5 minutes"
// after
timeout: "5m"
Defensive patterns

Strategy: validation

Validate before calling

func parseDur(s any) (time.Duration, error) {
  if n := cast.ToInt(s); n > 0 { return time.Duration(n) * time.Millisecond, nil }
  return time.ParseDuration(cast.ToString(s))
}

Prevention

When it happens

Trigger: Calling types.ToDurationE with a malformed duration string (e.g. 'fast', '5 min', '1d'), an empty string with no positive integer, or a non-string non-int type that cast cannot coerce.

Common situations: Config values for `timeout`, `caches` expiry, or build timeouts expressed in non-Go syntax (e.g. '1 day', '500ms' is fine, but '500' without a unit fallback works because the int path treats it as ms).

Related errors


AI-assisted analysis of gohugoio/hugo@52c9bd7908 (2026-08-09). Data as JSON: /api/errors/54625cf05bbad9b6. Report an issue: GitHub.

Appendix: source

Thrown at common/types/convert.go:40

	"github.com/spf13/cast"
)

// ToDuration converts v to time.Duration.
// See ToDurationE if you need to handle errors.
func ToDuration(v any) time.Duration {
	d, _ := ToDurationE(v)
	return d
}

// ToDurationE converts v to time.Duration.
func ToDurationE(v any) (time.Duration, error) {
	if n := cast.ToInt(v); n > 0 {
		return time.Duration(n) * time.Millisecond, nil
	}
	d, err := time.ParseDuration(cast.ToString(v))
	if err != nil {
		return 0, fmt.Errorf("cannot convert %v to time.Duration", v)
	}
	return d, nil
}

// ToStringSlicePreserveString is the same as ToStringSlicePreserveStringE,
// but it never fails.
func ToStringSlicePreserveString(v any) []string {
	vv, _ := ToStringSlicePreserveStringE(v)
	return vv
}

// ToStringSlicePreserveStringE converts v to a string slice.
// If v is a string, it will be wrapped in a string slice.
func ToStringSlicePreserveStringE(v any) ([]string, error) {
	if v == nil {
		return nil, nil
	}
	if sds, ok := v.(string); ok {

View on GitHub (pinned to 52c9bd7908)