gohugoio/hugo · error
scale must be an integer greater than or equal to 2
Error message
scale must be an integer greater than or equal to 2
What it means
The `scale` option of `images.QR` is the number of image pixels per QR module. Hugo requires scale ≥ 2 (default 4) because a scale below 2 produces a QR code too small/dense to be reliably scanned. Values are weak-decoded via mapstructure, so a non-integer that truncates below 2 also fails.
Source
Thrown at tpl/images/images.go:159
if text == "" {
return nil, errors.New("cannot encode an empty string")
}
if len(args) == 2 {
err := mapstructure.WeakDecode(args[1], &opts)
if err != nil {
return nil, err
}
}
level, ok := qrErrorCorrectionLevels[opts.Level]
if !ok {
return nil, errors.New("error correction level must be one of low, medium, quartile, or high")
}
if opts.Scale < 2 {
return nil, errors.New("scale must be an integer greater than or equal to 2")
}
targetPath := path.Join(opts.TargetDir, fmt.Sprintf("qr_%s.png", hashing.HashStringHex(text, opts)))
r, err := ns.createClient.FromOpts(
create.Options{
TargetPath: targetPath,
TargetPathHasHash: true,
CreateContent: func() (func() (hugio.ReadSeekCloser, error), error) {
code, err := qr.Encode(text, level)
if err != nil {
return nil, err
}
code.Scale = opts.Scale
png := code.PNG()
return func() (hugio.ReadSeekCloser, error) {
return hugio.NewReadSeekerNoOpCloserFromBytes(png), nil
}, nilView on GitHub ↗ (pinned to 8a468df065)
Solutions
- Set `scale` to an integer of 2 or more: `(dict "scale" 2)`.
- Omit the option to use the default of 4.
- If you need a smaller rendered image, keep scale ≥ 2 and size it with CSS or `.Resize` instead.
Example fix
<!-- before -->
{{ $qr := images.QR $text (dict "scale" 1) }}
<!-- after -->
{{ $qr := images.QR $text (dict "scale" 2) }} Defensive patterns
Strategy: validation
Validate before calling
{{ $scale := int (.Params.qrScale | default 4) }}
{{ if lt $scale 2 }}{{ $scale = 2 }}{{ end }}
{{ $qr := images.QR $text (dict "scale" $scale) }} Prevention
- QR scale must be an integer ≥ 2 — clamp or validate before the call
- Convert stringly params with `int` first; a string "4" is not an integer
- Document the minimum in your shortcode docs so content authors don't pass 1 or 0
When it happens
Trigger: Calling `{{ images.QR $text (dict "scale" 1) }}`, `scale 0`, or a negative scale; passing a string or float that weak-decodes to an int below 2.
Common situations: Trying to shrink the output image by lowering scale instead of resizing the resulting resource; computing scale from a template expression that yields 0 or 1; assuming scale is a multiplier where 1 means original size.
Related errors
- error correction level must be one of low, medium, quartile,
- cannot encode an empty string
- errKeyIsEmptyString
- invalid options type: %w
- %q is not a valid duration unit
AI-assisted analysis of gohugoio/hugo@8a468df065 (2026-07-31).
Data as JSON: /data/errors/b92743088156e165.json.
Report an issue: GitHub ↗.