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
- Lower precision to 20 or fewer decimal places.
- Clamp the precision value from config/front matter before passing it.
- 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
- Clamp precision values coming from config or front matter.
- Double-check units (basis points vs decimal places) when computing precision.
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
- too many fields in options parameter to NumFmt
- aligny must be one of top, center, bottom
- cardinalityThreshold threshold must be between 0 and 100
- config needs a filename
- empty path is reserved for the home page
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)