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] = name

View on GitHub (pinned to e9452d6e78)

Solutions

  1. Pass a value of exactly swarm.Node{} or swarm.Service{} as the type selector: r.Resolve(ctx, swarm.Node{}, nodeID).
  2. If resolving a new object type, add a case for it in IDResolver.get with the corresponding client inspect call.
  3. 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


AI-assisted analysis of docker/cli@e9452d6e78 (2026-08-01). Data as JSON: /data/errors/3fb685d11452de08.json. Report an issue: GitHub.