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
Thrown by images.QR when the Scale option (image pixels per QR module) is less than 2. The default is 4, so this only fires when a user explicitly passes a Scale of 0, 1, or a negative number. A scale below 2 makes the QR code unscannable, so Hugo rejects it at tpl/images/images.go:158.
Solutions
- Set Scale to an integer >= 2 (4 is the default and a safe choice).
- Clamp from config: {{ $scale := math.Max 2 (.Param "qr_scale" | default 4) }}.
- Omit Scale to use the default of 4.
- Verify the config value is an integer, not a string or float.
Example fix
// before
{{ images.QR .Permalink (dict "Scale" 1) }}
// after
{{ images.QR .Permalink (dict "Scale" 4) }} Defensive patterns
Strategy: validation
Validate before calling
// Clamp the scale before calling images.QR:
{{ $scale := .Param "qr_scale" | default 4 }}
{{ if lt $scale 2 }}{{ $scale = 2 }}{{ end }}
{{ images.QR .Permalink (dict "Scale" $scale) }} Type guard
// Go caller:
func validScale(i int) bool { return i >= 2 } Prevention
- Keep Scale >= 2 (4 is the safe default).
- Clamp config-derived scale values to a minimum of 2.
- Ensure the config value is an integer, not a float or string.
When it happens
Trigger: Calling {{ images.QR "text" (dict "Scale" 1) }} or passing Scale 0/negative; passing a float like 1.5 that WeakDecode truncates to 1; pulling Scale from a config value set incorrectly.
Common situations: Trying to make a tiny QR code for compact layouts and underestimating the minimum; config param mis-typed as a string that decodes to 0; copying a snippet that used a different default.
Related errors
- cannot encode an empty string
- error correction level must be one of low, medium…
- both count and seq must be provided
- cannot index slice/array with nil
- complement needs at least two arguments
AI-assisted analysis of gohugoio/hugo@52c9bd7908 (2026-08-09).
Data as JSON: /api/errors/b92743088156e165.
Report an issue: GitHub.
Appendix: 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 52c9bd7908)