{"record":{"id":"664305ca40fc71e0","repo":"gohugoio/hugo","slug":"text-must-be-a-string","errorCode":null,"errorMessage":"text must be a string","messagePattern":"text must be a string","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"tpl/strings/truncate.go","lineNumber":73,"sourceCode":"\tcase 1:\n\t\ttextParam = options[0]\n\t\tellipsis = \" …\"\n\tcase 2:\n\t\ttextParam = options[1]\n\t\tellipsis, err = cast.ToStringE(options[0])\n\t\tif err != nil {\n\t\t\treturn \"\", errors.New(\"ellipsis must be a string\")\n\t\t}\n\t\tif _, ok := options[0].(template.HTML); !ok {\n\t\t\tellipsis = html.EscapeString(ellipsis)\n\t\t}\n\tdefault:\n\t\treturn \"\", errors.New(\"too many arguments passed to truncate\")\n\t}\n\n\ttext, err := cast.ToStringE(textParam)\n\tif err != nil {\n\t\treturn \"\", errors.New(\"text must be a string\")\n\t}\n\n\t_, isHTML := textParam.(template.HTML)\n\n\tif utf8.RuneCountInString(text) <= length {\n\t\tif isHTML {\n\t\t\treturn template.HTML(text), nil\n\t\t}\n\t\treturn template.HTML(html.EscapeString(text)), nil\n\t}\n\n\ttags := []htmlTag{}\n\tvar lastWordIndex, lastNonSpace, currentLen, endTextPos, nextTag int\n\n\tfor i, r := range text {\n\t\tif i < nextTag {\n\t\t\tcontinue\n\t\t}","sourceCodeStart":55,"sourceCodeEnd":91,"githubUrl":"https://github.com/gohugoio/hugo/blob/52c9bd7908b4d02d4d0ff8f82a888834d6ee10d2/tpl/strings/truncate.go#L55-L91","documentation":"Thrown by strings.Truncate when the text argument (resolved from options) cannot be cast to a string (tpl/strings/truncate.go:71-73). After the length and optional ellipsis are validated, the text must be string-convertible.","triggerScenarios":"Calling {{ truncate 50 .SomeNonStringableValue }} where the value is a struct, map, slice, or nil that cast.ToStringE rejects.","commonSituations":"Passing a complex object (e.g. a Page or slice) instead of a field like .Title; nil values from missing params; unexpected types from resources or data files.","solutions":["Pass a string field: {{ truncate 50 .Title }} instead of {{ truncate 50 . }}.","Render complex objects first, e.g. with .Plain or .Summary.","Default nil: {{ truncate 50 (default \"\" .MaybeText) }}."],"exampleFix":"// before\n{{ truncate 50 . }}\n// after\n{{ truncate 50 .Title }}","handlingStrategy":"type-guard","validationCode":"{{ with .Title }}{{ truncate 50 . }}{{ end }}","typeGuard":"{{/* guardString ensures a string-castable value */}}\n{{ define \"guardString\" }}{{ if . }}{{ if (eq (printf \"%T\" .) \"string\") }}{{ . }}{{ else }}{{ plainify . }}{{ end }}{{ end }}{{ end }}","tryCatchPattern":null,"preventionTips":["Pass string fields (.Title, .Plain) rather than whole objects.","Default nil with (default \"\" .MaybeText)."],"tags":["template-function","strings","truncate","type-coercion","argument"],"backgroundTag":null,"analyzedSha":"52c9bd7908b4d02d4d0ff8f82a888834d6ee10d2","analyzedAt":"2026-08-09T21:49:36.660Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}