{"id":"b97cbb66ca8bb2d5","repo":"gohugoio/hugo","slug":"start-argument-must-be-integer","errorCode":null,"errorMessage":"start argument must be integer","messagePattern":"start argument must be integer","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"tpl/strings/strings.go","lineNumber":330,"sourceCode":"\treturn replacer.Replace(ss), nil\n}\n\n// SliceString slices a string by specifying a half-open range with\n// two indices, start and end. 1 and 4 creates a slice including elements 1 through 3.\n// The end index can be omitted, it defaults to the string's length.\nfunc (ns *Namespace) SliceString(a any, startEnd ...any) (string, error) {\n\taStr, err := cast.ToStringE(a)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\tvar argStart, argEnd int\n\n\targNum := len(startEnd)\n\n\tif argNum > 0 {\n\t\tif argStart, err = cast.ToIntE(startEnd[0]); err != nil {\n\t\t\treturn \"\", errors.New(\"start argument must be integer\")\n\t\t}\n\t}\n\tif argNum > 1 {\n\t\tif argEnd, err = cast.ToIntE(startEnd[1]); err != nil {\n\t\t\treturn \"\", errors.New(\"end argument must be integer\")\n\t\t}\n\t}\n\n\tif argNum > 2 {\n\t\treturn \"\", errors.New(\"too many arguments\")\n\t}\n\n\tasRunes := []rune(aStr)\n\n\tif argNum > 0 && (argStart < 0 || argStart >= len(asRunes)) {\n\t\treturn \"\", errors.New(\"slice bounds out of range\")\n\t}\n","sourceCodeStart":312,"sourceCodeEnd":348,"githubUrl":"https://github.com/gohugoio/hugo/blob/8a468df065a75c1c7cf9f6850f32148746590ea5/tpl/strings/strings.go#L312-L348","documentation":"Hugo's `strings.SliceString` template function converts its optional first index argument with `cast.ToIntE`. If the value passed as the start index cannot be cast to an int (e.g. a string like \"abc\", a slice, or nil), the function fails with this error instead of guessing a default.","triggerScenarios":"Calling `slicestr` in a Hugo template with a non-integer start value: `{{ slicestr \"BatMan\" \"x\" }}`, or passing a template variable/param that resolves to a non-numeric string, map, or nil as the second argument.","commonSituations":"Site params read from front matter or config as strings that aren't numeric; accidentally passing the substring instead of an index; a `.Params` value that is unset (nil); confusing `slicestr` argument order with other functions.","solutions":["Pass an integer (or numeric string) as the start index, e.g. `{{ slicestr $s 1 }}`","If the value comes from front matter/params, convert it explicitly with `int`, e.g. `{{ slicestr $s (int .Params.start) }}`","Guard against unset params: `{{ with .Params.start }}{{ slicestr $s (int .) }}{{ end }}`"],"exampleFix":"// before\n{{ slicestr \"BatMan\" \"3\"x }}\n{{ slicestr .Title .Params.start }}  <!-- start is \"two\" -->\n// after\n{{ slicestr \"BatMan\" 3 }}\n{{ slicestr .Title (int .Params.start) }}","handlingStrategy":"type-guard","validationCode":"{{ $start := .start }}\n{{ if ne (printf \"%T\" $start) \"int\" }}{{ $start = int $start }}{{ end }}\n{{ substr .s $start }}","typeGuard":"{{/* narrow to int before calling substr */}}\n{{ $start := int (default 0 .start) }}","tryCatchPattern":"{{ with try (substr .s .start) }}{{ if .Err }}{{ warnf \"substr failed: %s\" .Err }}{{ else }}{{ .Value }}{{ end }}{{ end }}","preventionTips":["Cast site params and front matter values with `int` before passing them as substr's start argument — values from YAML/JSON front matter or URL params often arrive as strings or float64.","Never pass floats with fractional parts; substr requires an exact integer.","Add a default: `int (default 0 .start)` so nil params don't reach the call."],"tags":["hugo","templates","go","type-conversion","strings"],"analyzedSha":"8a468df065a75c1c7cf9f6850f32148746590ea5","analyzedAt":"2026-07-31T21:23:07.045Z","schemaVersion":2}