{"id":"3fb685d11452de08","repo":"docker/cli","slug":"unsupported-type","errorCode":null,"errorMessage":"unsupported type","messagePattern":"unsupported type","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cli/command/idresolver/idresolver.go","lineNumber":53,"sourceCode":"\t\t\t// TODO(thaJeztah): should error-handling be more specific, or is it ok to ignore any error?\n\t\t\treturn id, nil //nolint:nilerr // ignore nil-error being returned, as this is a best-effort.\n\t\t}\n\t\tif res.Node.Spec.Annotations.Name != \"\" {\n\t\t\treturn res.Node.Spec.Annotations.Name, nil\n\t\t}\n\t\tif res.Node.Description.Hostname != \"\" {\n\t\t\treturn res.Node.Description.Hostname, nil\n\t\t}\n\t\treturn id, nil\n\tcase swarm.Service:\n\t\tres, err := r.client.ServiceInspect(ctx, id, client.ServiceInspectOptions{})\n\t\tif err != nil {\n\t\t\t// TODO(thaJeztah): should error-handling be more specific, or is it ok to ignore any error?\n\t\t\treturn id, nil //nolint:nilerr // ignore nil-error being returned, as this is a best-effort.\n\t\t}\n\t\treturn res.Service.Spec.Annotations.Name, nil\n\tdefault:\n\t\treturn \"\", errors.New(\"unsupported type\")\n\t}\n}\n\n// Resolve will attempt to resolve an ID to a Name by querying the manager.\n// Results are stored into a cache.\n// If the `-n` flag is used in the command-line, resolution is disabled.\nfunc (r *IDResolver) Resolve(ctx context.Context, t any, id string) (string, error) {\n\tif r.noResolve {\n\t\treturn id, nil\n\t}\n\tif name, ok := r.cache[id]; ok {\n\t\treturn name, nil\n\t}\n\tname, err := r.get(ctx, t, id)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\tr.cache[id] = name","sourceCodeStart":35,"sourceCodeEnd":71,"githubUrl":"https://github.com/docker/cli/blob/e9452d6e785f6e365712b9d71bd7517591773c86/cli/command/idresolver/idresolver.go#L35-L71","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nname, err := resolver.Resolve(ctx, &swarm.Node{}, task.NodeID)\n// after\nname, err := resolver.Resolve(ctx, swarm.Node{}, task.NodeID)","handlingStrategy":null,"validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":["go","docker-cli","swarm","type-switch","idresolver"],"analyzedSha":"e9452d6e785f6e365712b9d71bd7517591773c86","analyzedAt":"2026-08-01T07:09:22.474Z","schemaVersion":2}