docker/cli · error
unsupported type
Error message
unsupported type
What it means
IDResolver.get resolves swarm object IDs to human-readable names, but only supports two concrete types: swarm.Node and swarm.Service (matched via a type switch on the value's dynamic type). Any other type — including *swarm.Node/*swarm.Service pointers, since the switch matches value types only — falls to the default branch and returns this error. It signals a programming error in the caller, not a runtime/daemon problem.
Source
Thrown at cli/command/idresolver/idresolver.go:53
// TODO(thaJeztah): should error-handling be more specific, or is it ok to ignore any error?
return id, nil //nolint:nilerr // ignore nil-error being returned, as this is a best-effort.
}
if res.Node.Spec.Annotations.Name != "" {
return res.Node.Spec.Annotations.Name, nil
}
if res.Node.Description.Hostname != "" {
return res.Node.Description.Hostname, nil
}
return id, nil
case swarm.Service:
res, err := r.client.ServiceInspect(ctx, id, client.ServiceInspectOptions{})
if err != nil {
// TODO(thaJeztah): should error-handling be more specific, or is it ok to ignore any error?
return id, nil //nolint:nilerr // ignore nil-error being returned, as this is a best-effort.
}
return res.Service.Spec.Annotations.Name, nil
default:
return "", errors.New("unsupported type")
}
}
// Resolve will attempt to resolve an ID to a Name by querying the manager.
// Results are stored into a cache.
// If the `-n` flag is used in the command-line, resolution is disabled.
func (r *IDResolver) Resolve(ctx context.Context, t any, id string) (string, error) {
if r.noResolve {
return id, nil
}
if name, ok := r.cache[id]; ok {
return name, nil
}
name, err := r.get(ctx, t, id)
if err != nil {
return "", err
}
r.cache[id] = nameView on GitHub (pinned to e9452d6e78)
Solutions
- Pass a value of exactly swarm.Node{} or swarm.Service{} as the type selector: r.Resolve(ctx, swarm.Node{}, nodeID).
- If resolving a new object type, add a case for it in IDResolver.get with the corresponding client inspect call.
- If passing a pointer, dereference or use the value type literal instead.
Example fix
// before
name, err := resolver.Resolve(ctx, &swarm.Node{}, task.NodeID)
// after
name, err := resolver.Resolve(ctx, swarm.Node{}, task.NodeID) When it happens
Trigger: Calling IDResolver.Resolve(ctx, t, id) with t that is not exactly swarm.Node or swarm.Service — e.g. passing swarm.Task, a *swarm.Node pointer, a string, or a new swarm object type added without extending the type switch. Note noResolve=true or a cache hit bypasses the check entirely.
Common situations: Extending docker CLI swarm commands (e.g. task/secret/config listings) and reusing idresolver for a new object type without adding a case; passing a pointer instead of a value after a refactor; vendored moby API type moves changing which package's swarm.Node is passed.
Related errors
- plugin candidate path cannot be empty
- no output stream
- when using secret driver secret data must be empty
- error reading from STDIN: data is empty
- secret file is required
AI-assisted analysis of docker/cli@e9452d6e78 (2026-08-01).
Data as JSON: /data/errors/3fb685d11452de08.json.
Report an issue: GitHub.