gohugoio/hugo · error

invalid precision

Error message

invalid precision: %d

What it means

FormatNumber, FormatPercent, FormatCurrency, and FormatAccounting share castPrecisionNumber, which caps precision at 20 digits as a sanity guard. Any precision value above 20 is rejected. See lang.go:113-116.

Solutions

  1. Lower precision to 20 or fewer decimal places.
  2. Clamp the precision value from config/front matter before passing it.
  3. Reconsider whether such high precision is meaningful for the output.

Example fix

// before
{{ lang.FormatNumber 25 .Value }}

// after
{{ lang.FormatNumber 20 .Value }}
Defensive patterns

Strategy: validation

Validate before calling

// Clamp precision to the supported maximum before formatting.
if p > 20 { p = 20 }
// or reject:
if p > 20 { return "", fmt.Errorf("precision %d exceeds max 20", p) }

Prevention

When it happens

Trigger: {{ lang.FormatNumber 25 3.14159 }} passing a precision greater than 20.

Common situations: Precision sourced from front matter or config without bounds checking; off-by-one or unit confusion (e.g. treating basis points as decimal places).

Related errors


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

Appendix: source

Thrown at tpl/lang/lang.go:115

//
// The return value is formatted with at least two decimal places.
func (ns *Namespace) FormatAccounting(precision, currency, number any) (string, error) {
	p, n, err := ns.castPrecisionNumber(precision, number)
	if err != nil {
		return "", err
	}
	return ns.translator.FormatAccounting(n, p, cast.ToString(currency)), nil
}

func (ns *Namespace) castPrecisionNumber(precision, number any) (int, float64, error) {
	p, err := cast.ToIntE(precision)
	if err != nil {
		return 0, 0, err
	}

	// Sanity check.
	if p > 20 {
		return 0, 0, fmt.Errorf("invalid precision: %d", precision)
	}

	n, err := cast.ToFloat64E(number)
	if err != nil {
		return 0, 0, err
	}
	return p, n, nil
}

// FormatNumberCustom formats a number with the given precision. The first
// options parameter is a space-delimited string of characters to represent
// negativity, the decimal point, and grouping. The default value is `- . ,`.
// The second options parameter defines an alternate delimiting character.
//
// Note that numbers are rounded up at 5 or greater.
// So, with precision set to 0, 1.5 becomes `2`, and 1.4 becomes `1`.
//
// For a simpler function that adapts to the current language, see FormatNumber.

View on GitHub (pinned to 52c9bd7908)