{"record":{"id":"827a36b55289777c","repo":"kubernetes/kops","slug":"ssh-key-task-has-unexpected-type-t","errorCode":null,"errorMessage":"SSH key task has unexpected type %T","messagePattern":"SSH key task has unexpected type %T","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"upup/pkg/fi/cloudup/template_functions.go","lineNumber":1270,"sourceCode":"\n\t// Strip the trailing newline that json.Encoder.Encode appends.\n\treturn strings.TrimRight(buf.String(), \"\\n\"), nil\n}\n\n// HCloudSSHKey returns HCLOUD_SSH_KEY as the first SSH key ID.\nfunc (tf *TemplateFunctions) HCloudSSHKey() (string, error) {\n\ttasks, err := tf.TasksByType(\"SSHKey\")\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"listing SSH key tasks: %w\", err)\n\t}\n\tif len(tasks) == 0 {\n\t\treturn \"\", nil\n\t}\n\n\t// Use the first SSH key, since the autoscaler accepts a single HCLOUD_SSH_KEY.\n\tsshKey, ok := tasks[0].(*hetznertasks.SSHKey)\n\tif !ok {\n\t\treturn \"\", fmt.Errorf(\"SSH key task has unexpected type %T\", tasks[0])\n\t}\n\n\tif sshKey.ID != nil {\n\t\treturn strconv.FormatInt(fi.ValueOf(sshKey.ID), 10), nil\n\t}\n\n\treturn \"\", nil\n}\n\n// HCloudClusterConfigChecksum returns a sha256 checksum of the rendered JSON config.\nfunc (tf *TemplateFunctions) HCloudClusterConfigChecksum() (string, error) {\n\tjsonConfig, err := tf.HCloudClusterConfig()\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\tsum256 := sha256.Sum256([]byte(jsonConfig))\n\treturn fmt.Sprintf(\"%x\", sum256), nil","sourceCodeStart":1252,"sourceCodeEnd":1288,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/upup/pkg/fi/cloudup/template_functions.go#L1252-L1288","documentation":"Returned by HCloudSSHKey when the first task of type \"SSHKey\" in the task map is not actually a *hetznertasks.SSHKey. TasksByType matches by type name string, so a different task type registered under the same name (or a custom/wrapped SSHKey implementation) triggers this type-assertion failure.","triggerScenarios":"A task registered with type name \"SSHKey\" is of a concrete type other than *hetznertasks.SSHKey — e.g. a vendored/renamed SSHKey type, a wrapper struct, or a mock leaking into the build.","commonSituations":"Forking or wrapping hetznertasks.SSHKey and forgetting to keep the registered type; test doubles injected into the task map; kops/hetzner provider version drift where the task type moved packages.","solutions":["Log %T of the offending task to see its actual concrete type","Ensure only *hetznertasks.SSHKey from the hetznertasks package is registered as an SSHKey task","Remove wrappers/mocks from the production task map","Align vendored hetzner task package versions with kops"],"exampleFix":"// before: custom wrapper registered as SSHKey\ntasks[\"SSHKey\"] = &mySSHKeyWrapper{...}\n// after\nvar key *hetznertasks.SSHKey = &hetznertasks.SSHKey{Name: fi.PtrTo(\"default\"), ...}\ntasks[\"SSHKey\"] = key","handlingStrategy":"type-guard","validationCode":"tasks, err := tf.TasksByType(\"SSHKey\")\nif err != nil { return err }\nif len(tasks) > 0 {\n\tif _, ok := tasks[0].(*hetznertasks.SSHKey); !ok {\n\t\treturn fmt.Errorf(\"SSHKey task is %T, not *hetznertasks.SSHKey\", tasks[0])\n\t}\n}","typeGuard":"func isHetznerSSHKey(t fi.Task) (*hetznertasks.SSHKey, bool) {\n\tkey, ok := t.(*hetznertasks.SSHKey)\n\treturn key, ok\n}","tryCatchPattern":"sshKeyID, err := tf.HCloudSSHKey()\nif err != nil {\n\treturn fmt.Errorf(\"ssh key type mismatch: %w\", err)\n}","preventionTips":["Never register wrapper/mock types under the SSHKey task name in production builds","Keep hetznertasks package versions in sync with kops","Add unit tests asserting concrete task types after refactorings","Log %T when type assertions fail to speed diagnosis"],"tags":["type-assertion","hetzner","sshkey","kops"],"backgroundTag":"unexpected-task-type","analyzedSha":"4c8573c808a73d578c5eadc86d410646ea0b0d73","analyzedAt":"2026-09-05T04:13:19.212Z","contentChangedAt":"2026-09-05T04:13:19.212Z","schemaVersion":2},"datasetVersion":"2026-09-12T07:17:12.445Z"}