{"id":"b92743088156e165","repo":"gohugoio/hugo","slug":"scale-must-be-an-integer-greater-than-or-equal-to","errorCode":null,"errorMessage":"scale must be an integer greater than or equal to 2","messagePattern":"scale must be an integer greater than or equal to 2","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"tpl/images/images.go","lineNumber":159,"sourceCode":"\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\n\t\t\t\tpng := code.PNG()\n\t\t\t\treturn func() (hugio.ReadSeekCloser, error) {\n\t\t\t\t\treturn hugio.NewReadSeekerNoOpCloserFromBytes(png), nil\n\t\t\t\t}, nil","sourceCodeStart":141,"sourceCodeEnd":177,"githubUrl":"https://github.com/gohugoio/hugo/blob/8a468df065a75c1c7cf9f6850f32148746590ea5/tpl/images/images.go#L141-L177","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"<!-- before -->\n{{ $qr := images.QR $text (dict \"scale\" 1) }}\n<!-- after -->\n{{ $qr := images.QR $text (dict \"scale\" 2) }}","handlingStrategy":"validation","validationCode":"{{ $scale := int (.Params.qrScale | default 4) }}\n{{ if lt $scale 2 }}{{ $scale = 2 }}{{ end }}\n{{ $qr := images.QR $text (dict \"scale\" $scale) }}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["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"],"tags":["hugo","templates","images","qr","options","validation"],"analyzedSha":"8a468df065a75c1c7cf9f6850f32148746590ea5","analyzedAt":"2026-07-31T21:23:07.045Z","schemaVersion":2}