docker/cli · error

expected slice, got %T

Error message

expected slice, got %T

What it means

Returned by the 'join' template function (joinElements, used in docker --format Go templates and the table headers) when the argument piped to join is not nil, not a []string, and not an array, slice, or map. reflect.ValueOf(...).Kind() falls into the default branch and reports the actual Go type via %T.

Solutions

  1. Confirm the field is a slice/array/map in 'docker inspect --format "{{json .}}"' output before joining.
  2. If the field is a scalar string, drop join and use it directly: '{{.Image}}'.
  3. Wrap the value so join receives a slice, or pick the correct list-valued field (e.g. .Mounts, .Config.Env).

Example fix

# before
# .RepoTags is a []string -> OK; but piping a string field fails:
docker image ls --format '{{join .ID ","}}'
# after: join a real slice field
docker image ls --format '{{join .RepoTags ","}}'
Defensive patterns

Strategy: type-guard

Type guard

// joinElements accepts: nil, []string, arrays, slices, maps. Guard everything else out.
import "reflect"

func isJoinable(v any) bool {
    if v == nil { return true }
    if _, ok := v.([]string); ok { return true }
    switch reflect.ValueOf(v).Kind() {
    case reflect.Array, reflect.Slice, reflect.Map:
        return true
    }
    return false
}

// usage before rendering:
// if !isJoinable(field) { /* don't call {{join field}}; render it directly */ }

Try / catch

var buf bytes.Buffer
if err := tmpl.Execute(&buf, data); err != nil {
    // err text: expected slice, got <typename>
    return fmt.Errorf("template error (is the joined field a slice?): %w", err)
}

Prevention

When it happens

Trigger: Using '{{join .Field ","}}' in a '--format' template where .Field is a scalar (string, int, bool) or a struct rather than a slice/array/map. For example '{{join .Image ","}}' on a string field, or piping an integer.

Common situations: Authoring a custom --format and assuming a field is a list when the inspect JSON shows a string; piping the wrong sub-field; or using join on a single value that is not a collection.

Related errors


AI-assisted analysis of docker/cli@4f84911bfe (2026-08-07). Data as JSON: /api/errors/839d0a80c911a69b. Report an issue: GitHub.

Appendix: source

Thrown at templates/templates.go:137

		for i := range rv.Len() {
			if i > 0 {
				b.WriteString(sep)
			}
			_, _ = fmt.Fprint(&b, rv.Index(i).Interface())
		}
		return b.String(), nil

	case reflect.Map:
		var out []string
		for _, k := range rv.MapKeys() {
			out = append(out, fmt.Sprint(rv.MapIndex(k).Interface()))
		}
		// Not ideal, but trying to keep a consistent order
		sort.Strings(out)
		return strings.Join(out, sep), nil

	default:
		return "", fmt.Errorf("expected slice, got %T", elems)
	}
}

View on GitHub (pinned to 4f84911bfe)