gohugoio/hugo · error
cannot parse %q as a media type
Error message
cannot parse %q as a media type
What it means
Hugo's media.FromString parses a MIME string of the form 'mainType/subType' with an optional '+suffix' (e.g. 'text/html', 'application/rss+xml'). It splits the input on '/' and requires exactly two parts; anything else is rejected with this error. It exists to catch malformed media type identifiers early, before they propagate into output-format and content-type resolution.
Source
Thrown at media/mediaType.go:141
if err != nil {
return tp, err
}
for i, e := range ext {
ext[i] = strings.TrimPrefix(e, ".")
}
tp.SuffixesCSV = strings.Join(ext, ",")
tp.Delimiter = DefaultDelimiter
tp.init()
return tp, nil
}
// FromString creates a new Type given a type string on the form MainType/SubType and
// an optional suffix, e.g. "text/html" or "text/html+html".
func FromString(t string) (Type, error) {
t = strings.ToLower(t)
parts := strings.Split(t, "/")
if len(parts) != 2 {
return Type{}, fmt.Errorf("cannot parse %q as a media type", t)
}
mainType := parts[0]
subParts := strings.Split(parts[1], "+")
subType := strings.Split(subParts[0], ";")[0]
var suffix string
if len(subParts) > 1 {
suffix = subParts[1]
}
var typ string
if suffix != "" {
typ = mainType + "/" + subType + "+" + suffix
} else {
typ = mainType + "/" + subType
}View on GitHub ↗ (pinned to 8a468df065)
Solutions
- Fix the media type key/value in your config to the full 'mainType/subType' form, e.g. 'application/json' not 'json'.
- Check custom outputFormats entries — their mediaType must reference a full MIME string that exists under mediaTypes.
- If calling media.FromString in code, pass a MIME string, not a file extension; use FromStringAndExt to attach extensions.
Example fix
# before (hugo.toml) [mediaTypes."jsonfeed"] suffixes = ["json"] # after [mediaTypes."application/feed+json"] suffixes = ["json"]
Defensive patterns
Strategy: validation
Validate before calling
// Validate media type string before passing to Hugo config
import "mime"
if _, _, err := mime.ParseMediaType(mt); err != nil || !strings.Contains(mt, "/") {
return fmt.Errorf("invalid media type %q: must be main/sub form", mt)
} Try / catch
types, err := media.DecodeTypes(...)
if err != nil {
var pe *media.ParseError // or match message
log.Fatalf("media type config invalid: %v", err)
} Prevention
- Always write media types as main/subtype (e.g. text/html), never bare names
- Validate custom mediaTypes config entries with mime.ParseMediaType before building
- Copy suffix/delimiter settings from Hugo's built-in media type list rather than inventing formats
When it happens
Trigger: Calling media.FromString / FromStringAndExt with a string that doesn't contain exactly one '/', e.g. 'html', 'text', 'text/html/extra', or an empty string. In practice this happens when Hugo decodes the site config's mediaTypes/outputFormats sections and a key isn't a valid 'type/subtype' string.
Common situations: A custom mediaTypes entry in hugo.toml/config.toml keyed by just the suffix (e.g. [mediaTypes.'json'] instead of [mediaTypes.'application/json']); typos like 'text\html'; defining outputFormats with a mediaType value that is a bare name; programmatic use of the media package with file extensions instead of MIME strings.
Related errors
- target path %q is not a known content format
- unknown media type %q
- language %q not found
- unsupported format: %q
- failed to create workingDir: %w
AI-assisted analysis of gohugoio/hugo@8a468df065 (2026-07-31).
Data as JSON: /data/errors/d4e9508e97932612.json.
Report an issue: GitHub ↗.