gohugoio/hugo · error

can't slice item of type %s

Error message

can't slice item of type %s

What it means

Raised by the `slice` action when the item's reflect.Kind is not String, Array, or Slice (funcs.go:255-264). `slice` only supports the sliceable kinds; a struct, map, int, bool, chan, or func hits the default branch. The %s is the item's Go type.

Source

Thrown at tpl/internal/go_templates/texttemplate/funcs.go:264

	}
	var isNil bool
	if item, isNil = indirect(item); isNil {
		return reflect.Value{}, fmt.Errorf("slice of nil pointer")
	}
	if len(indexes) > 3 {
		return reflect.Value{}, fmt.Errorf("too many slice indexes: %d", len(indexes))
	}
	var cap int
	switch item.Kind() {
	case reflect.String:
		if len(indexes) == 3 {
			return reflect.Value{}, fmt.Errorf("cannot 3-index slice a string")
		}
		cap = item.Len()
	case reflect.Array, reflect.Slice:
		cap = item.Cap()
	default:
		return reflect.Value{}, fmt.Errorf("can't slice item of type %s", item.Type())
	}
	// set default values for cases item[:], item[i:].
	idx := [3]int{0, item.Len()}
	for i, index := range indexes {
		x, err := indexArg(index, cap)
		if err != nil {
			return reflect.Value{}, err
		}
		idx[i] = x
	}
	// given item[i:j], make sure i <= j.
	if idx[0] > idx[1] {
		return reflect.Value{}, fmt.Errorf("invalid slice index: %d > %d", idx[0], idx[1])
	}
	if len(indexes) < 3 {
		return item.Slice(idx[0], idx[1]), nil
	}
	// given item[i:j:k], make sure i <= j <= k.

View on GitHub (pinned to 52c9bd7908)

Solutions

  1. Print the type: `{{printf "%T" .X}}` to see what was actually passed.
  2. Change the template to use the appropriate accessor (range for maps, fields for structs).
  3. Change the data so the value is a string/array/slice before slicing.

Example fix

// before
{{slice .Meta 0 2}}   // .Meta is a map[string]string

// after
{{range $k, $v := .Meta}}{{$v}}{{end}}
Defensive patterns

Strategy: type-guard

Validate before calling

// Check the kind before slicing:
//   {{printf "%T" .X}}
// Only slice String/Array/Slice; otherwise range or access fields.

Type guard

func isSliceable(v interface{}) bool {
    if v == nil { return false }
    switch reflect.TypeOf(v).Kind() {
    case reflect.String, reflect.Slice, reflect.Array:
        return true
    }
    return false
}

Prevention

When it happens

Trigger: `{{slice .Map 0 1}}` on a map; `{{slice .Int 0}}` on an int; `{{slice .Time 0 4}}` on a struct like time.Time.

Common situations: Refactoring a field from a slice to a map or struct; passing the wrong variable to a partial that expects a slice; shortcodes that assume list input but receive a scalar.

Related errors


AI-assisted analysis of gohugoio/hugo@52c9bd7908 (2026-08-09). Data as JSON: /api/errors/bf4a6d6f1bde2f52. Report an issue: GitHub.