{"record":{"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/52c9bd7908b4d02d4d0ff8f82a888834d6ee10d2/tpl/images/images.go#L137-L173","documentation":"Thrown by images.QR when the Level option in the options map is not one of the four allowed keys (low, medium, quartile, high). Hugo looks up opts.Level in the qrErrorCorrectionLevels map (tpl/images/images.go:153) and rejects anything else, including typos, different casing, or numeric levels. The default is \"medium\" so the error only fires when a user supplies an explicit, invalid Level.","triggerScenarios":"Calling {{ images.QR \"text\" (dict \"Level\" \"Medium\") }} (wrong case), or \"L\"/\"M\"/\"Q\"/\"H\" (the qr.Level constants rather than the map keys), or \"high1\", or a value pulled from a config key that does not match the allowed set.","commonSituations":"Copying example code that used a different QR library's naming (e.g. \"L\"/\"M\"); user-defined config with site params.QRLevel set to an unsupported value; case sensitivity surprises since the map keys are all lowercase.","solutions":["Use one of the exact lowercase keys: low, medium, quartile, or high.","If the level comes from config, normalize it: {{ $level := lower .Site.Params.qr.level | default \"medium\" }} and validate against the set.","Omit Level entirely to accept the default \"medium\".","Check the value in front matter / config for typos or trailing whitespace."],"exampleFix":"// before\n{{ images.QR .Permalink (dict \"Level\" \"High\") }}\n\n// after\n{{ images.QR .Permalink (dict \"Level\" \"high\") }}","handlingStrategy":"validation","validationCode":"// Normalize and validate the level before passing to images.QR:\n{{ $level := lower (.Param \"qr_level\" | default \"medium\") }}\n{{ if in (slice \"low\" \"medium\" \"quartile\" \"high\") $level }}\n  {{ images.QR .Permalink (dict \"Level\" $level) }}\n{{ end }}","typeGuard":"// Go caller:\nvar validLevels = map[string]bool{\"low\": true, \"medium\": true, \"quartile\": true, \"high\": true}\nfunc validLevel(s string) bool { return validLevels[s] }","tryCatchPattern":null,"preventionTips":["Use lowercase level keys exactly: low, medium, quartile, high.","Normalize config-derived values with lower and validate against the set.","Omit Level to rely on the 'medium' default when unsure."],"tags":["hugo","template","qr-code","argument-validation","config"],"backgroundTag":null,"analyzedSha":"52c9bd7908b4d02d4d0ff8f82a888834d6ee10d2","analyzedAt":"2026-08-09T21:49:36.660Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}