gohugoio/hugo · error
invalid character
Error message
invalid character: %q
What it means
Thrown by stringToRune (tpl/transform/unmarshal.go:216), invoked while decoding CSV options. The Delimiter and Comment options must each be a single rune; a string with more than one character is rejected and the offending value is printed via %q. An empty string is allowed and maps to rune 0.
Solutions
- Provide exactly one character for delimiter/comment, e.g. "delimiter" ";"
- For tab, use the literal "\t" (single rune)
- Pre-split multi-character input outside the template before unmarshaling
Example fix
// before
{{ transform.Unmarshal (dict "format" "csv" "delimiter" ";,") $csv }}
// after
{{ transform.Unmarshal (dict "format" "csv" "delimiter" ";") $csv }} Defensive patterns
Strategy: validation
Validate before calling
func validSingleRune(s string) bool {
return len([]rune(s)) <= 1
}
// before building options:
if d, ok := opts["delimiter"]; ok && !validSingleRune(fmt.Sprint(d)) {
return errors.New("csv delimiter must be a single character")
} Prevention
- Use a single literal character for CSV delimiter/comment options
- Use "\t" for tab rather than the word 'tab'
- Validate option length before passing to transform.Unmarshal
When it happens
Trigger: Calling {{ transform.Unmarshal (dict "format" "csv" "delimiter" ";,") $csv }} (multi-char delimiter) or passing a Comment string longer than one character.
Common situations: Assuming multi-character CSV delimiters are supported; copying a config snippet that wraps the delimiter in quotes incorrectly; passing a word like 'tab' instead of the literal character.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
AI-assisted analysis of gohugoio/hugo@52c9bd7908 (2026-08-09).
Data as JSON: /api/errors/e6955b5325ef8ff4.
Report an issue: GitHub.
Appendix: source
Thrown at tpl/transform/unmarshal.go:216
}
func stringToRune(v any) (rune, error) {
s, err := cast.ToStringE(v)
if err != nil {
return 0, err
}
if len(s) == 0 {
return 0, nil
}
var r rune
for i, rr := range s {
if i == 0 {
r = rr
} else {
return 0, fmt.Errorf("invalid character: %q", v)
}
}
return r, nil
}
View on GitHub (pinned to 52c9bd7908)