gohugoio/hugo · error

unmarshal failed: %w

Error message

unmarshal failed: %w

What it means

This is the generic wrapper Hugo applies (via toFileError) when the format-specific decoder — json.Unmarshal, toml.Unmarshal, org, or the XML mapper — returns an error in UnmarshalTo. It means the format was recognized but the content is not valid for that format, and the wrapped %w preserves the underlying parser error with file position info where available.

Source

Thrown at parser/metadecoders/decoder.go:332

		case *any:
			*v = xmlValue
		}
	case TOML:
		err = toml.Unmarshal(data, v)
	case YAML:
		return UnmarshalYaml(data, v)
	case CSV:
		return d.unmarshalCSV(data, v)

	default:
		return fmt.Errorf("unmarshal of format %q is not supported", f)
	}

	if err == nil {
		return nil
	}

	return toFileError(f, data, fmt.Errorf("unmarshal failed: %w", err))
}

func (d Decoder) unmarshalCSV(data []byte, v any) error {
	r := csv.NewReader(bytes.NewReader(data))
	r.Comma = d.Delimiter
	r.Comment = d.Comment
	r.LazyQuotes = d.LazyQuotes

	records, err := r.ReadAll()
	if err != nil {
		return err
	}

	switch vv := v.(type) {
	case *any:
		switch d.TargetType {
		case "map":
			if len(records) < 2 {

View on GitHub ↗ (pinned to 8a468df065)

Solutions

  1. Read the wrapped error — it names the format and usually the line/column — and fix the syntax at that position in the named file.
  2. Validate the file with an external linter (jq for JSON, a TOML/XML validator) to pinpoint the malformed construct.
  3. For remote resources, verify the response body actually is the expected format (check for HTML error pages, rate-limit responses) before unmarshalling.

Example fix

// before (data/authors.json)
{
  "name": "Jane", // primary author
}
// after
{
  "name": "Jane"
}
Defensive patterns

Strategy: try-catch

Validate before calling

// cheap syntactic pre-check for JSON input
if format == metadecoders.JSON && !json.Valid(data) {
    return errors.New("invalid JSON input")
}

Try / catch

if err := decoder.UnmarshalTo(data, format, &v); err != nil {
    var typeErr *json.UnmarshalTypeError
    if errors.As(err, &typeErr) {
        // target type mismatch — fix the destination struct
    }
    // otherwise the source document is malformed; report file + err
    return fmt.Errorf("decode %s: %w", filename, err)
}

Prevention

When it happens

Trigger: Unmarshal of a data file, front matter, or transform.Unmarshal input whose bytes fail the underlying parser: malformed JSON (trailing commas, comments), invalid TOML (bad dates, duplicate keys), broken XML, or org-mode parse failures. YAML and CSV have their own paths, so this branch mostly surfaces JSON/TOML/XML/ORG syntax errors.

Common situations: Hand-edited data/*.json files with trailing commas or comments; TOML front matter with unquoted strings or duplicate keys; remote API responses that return an HTML error page while claiming JSON; merge-conflict markers left in data files; smart quotes pasted from a document into TOML.

Related errors


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