{"id":"de65544ea03b0072","repo":"gohugoio/hugo","slug":"error-correction-level-must-be-one-of-low-medium","errorCode":null,"errorMessage":"error correction level must be one of low, medium, quartile, or high","messagePattern":"error correction level must be one of low, medium, quartile, or high","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"tpl/images/images.go","lineNumber":155,"sourceCode":"\ttext, err := cast.ToStringE(args[0])\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tif text == \"\" {\n\t\treturn nil, errors.New(\"cannot encode an empty string\")\n\t}\n\n\tif len(args) == 2 {\n\t\terr := mapstructure.WeakDecode(args[1], &opts)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\n\tlevel, ok := qrErrorCorrectionLevels[opts.Level]\n\tif !ok {\n\t\treturn nil, errors.New(\"error correction level must be one of low, medium, quartile, or high\")\n\t}\n\n\tif opts.Scale < 2 {\n\t\treturn nil, errors.New(\"scale must be an integer greater than or equal to 2\")\n\t}\n\n\ttargetPath := path.Join(opts.TargetDir, fmt.Sprintf(\"qr_%s.png\", hashing.HashStringHex(text, opts)))\n\n\tr, err := ns.createClient.FromOpts(\n\t\tcreate.Options{\n\t\t\tTargetPath:        targetPath,\n\t\t\tTargetPathHasHash: true,\n\t\t\tCreateContent: func() (func() (hugio.ReadSeekCloser, error), error) {\n\t\t\t\tcode, err := qr.Encode(text, level)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn nil, err\n\t\t\t\t}\n\t\t\t\tcode.Scale = opts.Scale","sourceCodeStart":137,"sourceCodeEnd":173,"githubUrl":"https://github.com/gohugoio/hugo/blob/8a468df065a75c1c7cf9f6850f32148746590ea5/tpl/images/images.go#L137-L173","documentation":"`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.","triggerScenarios":"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\"`.","commonSituations":"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.","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`."],"exampleFix":"<!-- before -->\n{{ $qr := images.QR $text (dict \"level\" \"H\") }}\n<!-- after -->\n{{ $qr := images.QR $text (dict \"level\" \"high\") }}","handlingStrategy":"validation","validationCode":"{{ $level := .Params.qrLevel | default \"medium\" }}\n{{ if not (in (slice \"low\" \"medium\" \"quartile\" \"high\") $level) }}\n  {{ errorf \"invalid qrLevel %q\" $level }}\n{{ end }}\n{{ $qr := images.QR $text (dict \"level\" $level) }}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["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"],"tags":["hugo","templates","images","qr","options","validation"],"analyzedSha":"8a468df065a75c1c7cf9f6850f32148746590ea5","analyzedAt":"2026-07-31T21:23:07.045Z","schemaVersion":2}