{"record":{"id":"cc8c0f74094fd4d8","repo":"kubernetes/kops","slug":"unexpected-target-type-for-deletion-t-cc8c0f","errorCode":null,"errorMessage":"unexpected target type for deletion: %T","messagePattern":"unexpected target type for deletion: %T","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"upup/pkg/fi/cloudup/awstasks/network_load_balancer.go","lineNumber":725,"sourceCode":"// FindDeletions schedules deletion of load balancer revisions that are no longer in use.\nfunc (e *NetworkLoadBalancer) FindDeletions(context *fi.CloudupContext) ([]fi.CloudupDeletion, error) {\n\treturn e.deletions, nil\n}\n\n// deleteNLB tracks a NLB that we're going to delete\n// It implements fi.CloudupDeletion\ntype deleteNLB struct {\n\tobj *awsup.LoadBalancerInfo\n}\n\nvar _ fi.CloudupDeletion = (*deleteNLB)(nil)\n\nfunc (d *deleteNLB) Delete(t fi.CloudupTarget) error {\n\tctx := context.TODO()\n\n\tawsTarget, ok := t.(*awsup.AWSAPITarget)\n\tif !ok {\n\t\treturn fmt.Errorf(\"unexpected target type for deletion: %T\", t)\n\t}\n\n\tarn := d.obj.ARN()\n\tklog.V(2).Infof(\"deleting load balancer %q\", arn)\n\tif _, err := awsTarget.Cloud.ELBV2().DeleteLoadBalancer(ctx, &elbv2.DeleteLoadBalancerInput{\n\t\tLoadBalancerArn: &arn,\n\t}); err != nil {\n\t\treturn fmt.Errorf(\"error deleting ELB LoadBalancer %q: %w\", arn, err)\n\t}\n\n\treturn nil\n}\n\n// String returns a string representation of the task\nfunc (d *deleteNLB) String() string {\n\treturn d.TaskName() + \"-\" + d.Item()\n}\n","sourceCodeStart":707,"sourceCodeEnd":743,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/upup/pkg/fi/cloudup/awstasks/network_load_balancer.go#L707-L743","documentation":"deleteNLB.Delete type-asserts the fi.CloudupTarget to *awsup.AWSAPITarget and returns this error when the assertion fails. It is a programming/assembly error: the delete delegator was invoked with a target type other than the AWS API target. The %T verb prints the actual dynamic type received.","triggerScenarios":"Invoking deleteNLB.Delete with any fi.CloudupTarget that is not *awsup.AWSAPITarget — e.g. a dry-run/target passed into the deletion path, or a custom target type.","commonSituations":"Running deletion through a non-AWS target (e.g. a target built for a different cloud or a testing stub); code changes in kOps target wiring that route NLB deletion through the wrong target.","solutions":["Ensure NLB deletion is invoked with an *awsup.AWSAPITarget created for the cluster's cloud","Check how the delete delegator is registered/assembled in the task map","If writing tests, pass awsup.NewAWSAPITarget(cloud) rather than a mock target"],"exampleFix":"// before\ntarget := myMockTarget // not AWSAPITarget\ndelegator.Delete(target)\n// after\nawsTarget := awsup.NewAWSAPITarget(cloud)\ndelegator.Delete(awsTarget)","handlingStrategy":"type-guard","validationCode":"if _, ok := target.(*awsup.AWSAPITarget); !ok {\n  return fmt.Errorf(\"deleteNLB requires *awsup.AWSAPITarget, got %T\", target)\n}","typeGuard":"func asAWSAPITarget(t fi.CloudupTarget) (*awsup.AWSAPITarget, bool) {\n  at, ok := t.(*awsup.AWSAPITarget)\n  return at, ok\n}","tryCatchPattern":"awsTarget, ok := t.(*awsup.AWSAPITarget)\nif !ok { return fmt.Errorf(\"unexpected target type for deletion: %T\", t) }","preventionTips":["Always construct deletion delegators with awsup.NewAWSAPITarget(cloud)","Don't pass dry-run or mock targets into real deletion paths","Review target wiring after refactors of the apply machinery"],"tags":["aws","type-assertion","kops-internals"],"backgroundTag":"unexpected-target-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"}