{"id":"d9cf7018694624b4","repo":"gohugoio/hugo","slug":"front-matter-field-q-must-be-a-map-w","errorCode":null,"errorMessage":"front matter field %q must be a map: %w","messagePattern":"front matter field %q must be a map: %w","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"hugolib/page__meta.go","lineNumber":682,"sourceCode":"params:\n  build: \"My Build\"\n---\n´\n\n`\n\t\t}\n\t\treturn fmt.Errorf(\"failed to decode build config in front matter: %s%s\", err, msgDetail)\n\t}\n\n\tvar draft, published, isCJKLanguage *bool\n\tvar userParams map[string]any\n\tfor k, v := range pcfg.Params {\n\t\tloki := strings.ToLower(k)\n\n\t\tif loki == \"params\" {\n\t\t\tvv, err := hmaps.ToParamsAndPrepare(v)\n\t\t\tif err != nil {\n\t\t\t\treturn fmt.Errorf(\"front matter field %q must be a map: %w\", k, err)\n\t\t\t}\n\t\t\tuserParams = vv\n\t\t\tdelete(pcfg.Params, k)\n\t\t\tcontinue\n\t\t}\n\n\t\tif loki == \"published\" { // Intentionally undocumented\n\t\t\tvv, err := cast.ToBoolE(v)\n\t\t\tif err == nil {\n\t\t\t\tpublished = &vv\n\t\t\t}\n\t\t\t// published may also be a date\n\t\t\tcontinue\n\t\t}\n\n\t\tif ps.s.frontmatterHandler.IsDateKey(loki) {\n\t\t\tcontinue\n\t\t}","sourceCodeStart":664,"sourceCodeEnd":700,"githubUrl":"https://github.com/gohugoio/hugo/blob/8a468df065a75c1c7cf9f6850f32148746590ea5/hugolib/page__meta.go#L664-L700","documentation":"The reserved `params` front matter key must be a map of user-defined parameters. Hugo runs it through hmaps.ToParamsAndPrepare, which lower-cases keys and normalizes nested maps; if the value isn't map-shaped the conversion fails and the whole page build errors, because Hugo cannot merge arbitrary scalars into .Params.","triggerScenarios":"Front matter contains `params:` with a non-map value — a string, number, or list (e.g. `params: foo` or `params:\\n  - a\\n  - b`). Any page processed by hugolib with such front matter triggers it during pageMeta setup.","commonSituations":"Users who previously used `params` as their own scalar field, YAML indentation mistakes that turn an intended map into a string or list, or TOML `params = \"x\"` instead of a `[params]` table.","solutions":["Make `params` a map: `params:\\n  myKey: myValue` (YAML) or `[params]` table (TOML).","If you wanted a single custom value, nest it under params rather than replacing params itself.","Check YAML indentation — child keys must be indented under `params:`."],"exampleFix":"# before\n---\nparams: featured\n---\n# after\n---\nparams:\n  featured: true\n---","handlingStrategy":"type-guard","validationCode":"// Check reserved map-typed fields (build, sitemap, outputs config, etc.)\nfor _, k := range []string{\"build\", \"sitemap\"} {\n    if v, ok := fm[k]; ok {\n        if _, ok := v.(map[string]any); !ok {\n            return fmt.Errorf(\"front matter %q must be a map\", k)\n        }\n    }\n}","typeGuard":"func asMap(v any) (map[string]any, bool) {\n    m, ok := v.(map[string]any)\n    return m, ok\n}","tryCatchPattern":"if err := h.Build(config); err != nil {\n    var pe *herrors.ErrorWithFileContext\n    if errors.As(err, &pe) {\n        // pinpoint the file whose field has the wrong type\n    }\n    return err\n}","preventionTips":["Write map-typed front matter fields as nested maps, not scalar strings (e.g. `build:\\n  render: never`, not `build: never`)","Use %w-aware errors.As/errors.Is to surface the wrapped decode error with file context","Add a front matter schema check to CI to catch scalar-vs-map mistakes early"],"tags":["hugo","front-matter","params","yaml"],"analyzedSha":"8a468df065a75c1c7cf9f6850f32148746590ea5","analyzedAt":"2026-07-31T21:23:07.045Z","schemaVersion":2}