gohugoio/hugo · error
error correction level must be one of low, medium, quartile,
Error message
error correction level must be one of low, medium, quartile, or high
What it means
`images.QR` accepts an options map whose `level` sets the QR error-correction level. Hugo looks the value up in a fixed map (`low`, `medium`, `quartile`, `high` → qr.L/M/Q/H) and rejects anything else. The default is `medium` when the option is omitted.
Source
Thrown at tpl/images/images.go:155
text, err := cast.ToStringE(args[0])
if err != nil {
return nil, err
}
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.ScaleView on GitHub ↗ (pinned to 8a468df065)
Solutions
- Use one of the exact strings: `low`, `medium`, `quartile`, or `high` (lowercase).
- Map other libraries' L/M/Q/H notation to the corresponding word before passing it.
- Omit `level` entirely to get the default `medium`.
Example fix
<!-- before -->
{{ $qr := images.QR $text (dict "level" "H") }}
<!-- after -->
{{ $qr := images.QR $text (dict "level" "high") }} Defensive patterns
Strategy: validation
Validate before calling
{{ $level := .Params.qrLevel | default "medium" }}
{{ if not (in (slice "low" "medium" "quartile" "high") $level) }}
{{ errorf "invalid qrLevel %q" $level }}
{{ end }}
{{ $qr := images.QR $text (dict "level" $level) }} Prevention
- Only use "low", "medium", "quartile", or "high" for the QR level option
- Whitelist-check user/front-matter supplied levels with `in` before passing
- Lowercase the value before checking — the option is case-sensitive
When it happens
Trigger: Calling `{{ images.QR $text (dict "level" "h") }}` or any `level` value outside the four exact lowercase names — e.g. `"L"`, `"High"`, `"25%"`, or a typo like `"quartlie"`.
Common situations: Using single-letter levels (L/M/Q/H) familiar from other QR libraries; capitalizing the level name; passing a percentage value from other tools' terminology.
Related errors
- scale must be an integer greater than or equal to 2
- 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/de65544ea03b0072.json.
Report an issue: GitHub ↗.