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

  1. Fix the media type key/value in your config to the full 'mainType/subType' form, e.g. 'application/json' not 'json'.
  2. Check custom outputFormats entries — their mediaType must reference a full MIME string that exists under mediaTypes.
  3. 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

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


AI-assisted analysis of gohugoio/hugo@8a468df065 (2026-07-31). Data as JSON: /data/errors/d4e9508e97932612.json. Report an issue: GitHub ↗.