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
- Confirm the field is a slice/array/map in 'docker inspect --format "{{json .}}"' output before joining.
- If the field is a scalar string, drop join and use it directly: '{{.Image}}'.
- 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
- Inspect the data shape first: 'docker <obj> inspect --format "{{json .}}"'.
- Only join fields that are arrays/slices/maps; render scalars directly.
- Remember HeaderFunctions overrides 'join' to take a string — only the body 'join' requires a slice.
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
- cannot supply extra formatting options to the pretty…
- cannot supply extra formatting options to the pretty…
- cannot supply extra formatting options to the pretty…
- cannot supply extra formatting options to the pretty…
- --format is not yet supported with --tree
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)