{"record":{"id":"b0ea1be541507acd","repo":"gohugoio/hugo","slug":"stoplevel-w","errorCode":null,"errorMessage":"stopLevel: %w","messagePattern":"stopLevel: %w","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"markup/tableofcontents/tableofcontents.go","lineNumber":163,"sourceCode":"\t\theading = heading.Headings[len(heading.Headings)-1]\n\t}\n\theading.Headings = append(heading.Headings, h)\n}\n\n// ToHTML renders the ToC as HTML.\nfunc (toc *Fragments) ToHTML(startLevel, stopLevel any, ordered bool) (template.HTML, error) {\n\tif toc == nil {\n\t\treturn \"\", nil\n\t}\n\n\tiStartLevel, err := cast.ToIntE(startLevel)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"startLevel: %w\", err)\n\t}\n\n\tiStopLevel, err := cast.ToIntE(stopLevel)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"stopLevel: %w\", err)\n\t}\n\n\tb := &tocBuilder{\n\t\ts:          strings.Builder{},\n\t\th:          toc.Headings,\n\t\tstartLevel: iStartLevel,\n\t\tstopLevel:  iStopLevel,\n\t\tordered:    ordered,\n\t}\n\tb.Build()\n\treturn template.HTML(b.s.String()), nil\n}\n\nfunc (toc Fragments) walk(fn func(*Heading)) {\n\tfor _, h := range toc.Headings {\n\t\th.walk(fn)\n\t}\n}","sourceCodeStart":145,"sourceCodeEnd":181,"githubUrl":"https://github.com/gohugoio/hugo/blob/52c9bd7908b4d02d4d0ff8f82a888834d6ee10d2/markup/tableofcontents/tableofcontents.go#L145-L181","documentation":"Returned by Fragments.ToHTML when cast.ToIntE(stopLevel) fails: the stopLevel argument is not convertible to int. Identical shape to the startLevel error but for the stop/end level. Uses %w so the underlying cast error is unwrappable. Note a stopLevel of -1 is a valid sentinel meaning 'include all'.","triggerScenarios":"Calling Fragments.ToHTML(start, stop, ordered) with stop set to a non-integer string, e.g. ToHTML(2, \"3\", false) where \"3\" is a string, or ToHTML(2, nil, false). Fires from a layout partial rendering the ToC.","commonSituations":"Template params read from front matter/section params as strings; a partial receiving a shortcode arg as string; passing .Site.Params.toc.end_level without conversion; accidentally passing an ordered bool into the stopLevel slot.","solutions":["Pass stopLevel as an int (use -1 to include all levels).","Coerce the source value: {{ $stop := int (.Params.stop_level | default 3) }}.","Double-check argument order: ToHTML(startLevel, stopLevel, ordered)."],"exampleFix":"{{/* before */}}\n{{ .Fragments.ToHTML 2 .Params.end_level true }}\n\n{{/* after */}}\n{{ .Fragments.ToHTML 2 (int (.Params.end_level | default 3)) true }}","handlingStrategy":"type-guard","validationCode":"// Coerce stopLevel; -1 means include all.\nfunc toStopLevel(v any, def int) int {\n    switch t := v.(type) {\n    case int:\n        return t\n    case float64:\n        return int(t)\n    case string:\n        if n, err := strconv.Atoi(t); err == nil {\n            return n\n        }\n    }\n    return def\n}","typeGuard":"func isIntLike(v any) bool {\n    switch v.(type) {\n    case int, int64, float64:\n        return true\n    case string:\n        _, err := strconv.Atoi(v.(string))\n        return err == nil\n    }\n    return false\n}","tryCatchPattern":"html, err := frags.ToHTML(start, stop, ordered)\nif err != nil && strings.HasPrefix(err.Error(), \"stopLevel:\") {\n    html, err = frags.ToHTML(start, 3, ordered)\n}","preventionTips":["Pass stopLevel as int; use -1 deliberately to include all levels.","Keep argument order straight: (startLevel, stopLevel, ordered).","Coerce front-matter strings in the template."],"tags":["table-of-contents","template","type-coercion","validation"],"backgroundTag":null,"analyzedSha":"52c9bd7908b4d02d4d0ff8f82a888834d6ee10d2","analyzedAt":"2026-08-09T21:49:36.660Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}