gohugoio/hugo · error

cannot encode an empty string

Error message

cannot encode an empty string

What it means

Thrown by the images.QR template function when the text argument passed to it is an empty string. The QR encoder (rsc.io/qr) has nothing to encode, so Hugo rejects the input explicitly before attempting generation rather than producing a meaningless blank code. The check happens immediately after cast.ToStringE succeeds in tpl/images/images.go:142.

Solutions

  1. Guard with an {{ if qrText }} ... {{ end }} block around the images.QR call so empty values skip generation.
  2. Provide a fallback: {{ $text := .Param "qr_text" | default .Permalink }} before calling images.QR.
  3. Filter the source collection with where to exclude entries whose target field is empty before the QR loop.
  4. If the empty value is unexpected, log it ({{ warnf "empty QR text for %q" .Path }}) to find which content item is missing data.

Example fix

// before
{{ $qr := images.QR .Param "code" }}

// after
{{ $code := .Param "code" }}
{{ if $code }}
  {{ $qr := images.QR $code }}
{{ end }}
Defensive patterns

Strategy: validation

Validate before calling

// In a Hugo template, validate before calling images.QR:
{{ $text := .Param "qr_text" }}
{{ if $text }}
  {{ $qr := images.QR $text }}
{{ end }}

Type guard

// Go caller using the images.Namespace directly:
func nonEmptyString(v any) (string, bool) {
    s, ok := v.(string)
    return s, ok && s != ""
}

Prevention

When it happens

Trigger: Calling {{ images.QR "" }} or {{ images.QR someVar }} where someVar evaluates to an empty string (e.g. an unset page param, an empty .Title, or a scratch/default that resolved to ""). Also when the first positional arg is whitespace-only but cast to a trimmed empty string.

Common situations: Looping over a collection where some entries have no URL/identifier and generating a QR code per entry; using {{ .Param "qr_text" }} without a default; reading from front matter that was left blank; migrating content where a field was renamed and old pages now resolve to empty.

Related errors


AI-assisted analysis of gohugoio/hugo@52c9bd7908 (2026-08-09). Data as JSON: /api/errors/e8783ed9958e92aa. Report an issue: GitHub.

Appendix: source

Thrown at tpl/images/images.go:143

		Level     string // error correction level; one of low, medium, quartile, or high
		Scale     int    // number of image pixels per QR code module
		TargetDir string // target directory relative to publishDir
	}{
		Level: qrDefaultErrorCorrectionLevel,
		Scale: qrDefaultScale,
	}

	if len(args) == 0 || len(args) > 2 {
		return nil, errors.New("requires 1 or 2 arguments")
	}

	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")
	}

View on GitHub (pinned to 52c9bd7908)