{"record":{"id":"893045e3a9ddd76e","repo":"kubernetes/kops","slug":"unexpected-target-type-for-deletion-t","errorCode":null,"errorMessage":"unexpected target type for deletion: %T","messagePattern":"unexpected target type for deletion: %T","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"upup/pkg/fi/cloudup/awstasks/autoscalinggroup.go","lineNumber":1086,"sourceCode":"\tautoScalingGroupName string\n\ttargetGroupARN       string\n}\n\nvar _ fi.CloudupDeletion = (*deleteAutoscalingTargetGroupAttachment)(nil)\n\nfunc buildDeleteAutoscalingTargetGroupAttachment(autoScalingGroupName string, targetGroupARN string) *deleteAutoscalingTargetGroupAttachment {\n\td := &deleteAutoscalingTargetGroupAttachment{}\n\td.autoScalingGroupName = autoScalingGroupName\n\td.targetGroupARN = targetGroupARN\n\treturn d\n}\n\nfunc (d *deleteAutoscalingTargetGroupAttachment) 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\treq := &autoscaling.DetachLoadBalancerTargetGroupsInput{\n\t\tAutoScalingGroupName: aws.String(d.autoScalingGroupName),\n\t\tTargetGroupARNs:      []string{d.targetGroupARN},\n\t}\n\tif _, err := awsTarget.Cloud.Autoscaling().DetachLoadBalancerTargetGroups(ctx, req); err != nil {\n\t\treturn fmt.Errorf(\"failed to detach target groups from autoscaling group: %v\", err)\n\t}\n\n\treturn nil\n}\n\nfunc (d *deleteAutoscalingTargetGroupAttachment) TaskName() string {\n\treturn \"autoscaling-elb-attachment\"\n\n}\nfunc (d *deleteAutoscalingTargetGroupAttachment) Item() string {","sourceCodeStart":1068,"sourceCodeEnd":1104,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/upup/pkg/fi/cloudup/awstasks/autoscalinggroup.go#L1068-L1104","documentation":"deleteAutoscalingTargetGroupAttachment.Delete expects the target to be an *awsup.AWSAPITarget; any other fi.CloudupTarget type means the delete is being executed against the wrong target type (e.g. a Terraform or dry-run target). This is an internal type-assertion guard.","triggerScenarios":"Running a deletion flow for the target group attachment with a target that is not AWSAPITarget — e.g. `kops delete cluster` with --targets terraform, or a custom target passed to fi apply/delete.","commonSituations":"Deletion during terraform-target runs where AWS API deletions are not applicable; unit/integration tests invoking Delete with mock targets; tooling that drives fi targets programmatically.","solutions":["Run deletion with the AWS API target (omit --target terraform / use the default apply target) so ASG attachments can be detached via the API.","With --target terraform, rely on plan output instead of expecting API-side deletion.","If seen in tests, provide an awsup.AWSAPITarget (or a mocked equivalent) to the Delete call."],"exampleFix":"// before\nkops delete cluster --name cluster --target terraform\n// after (actual API deletion)\nkops delete cluster --name cluster --yes","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"func isAWSAPITarget(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 {\n  klog.V(2).Infof(\"skipping API deletion for target %T (terraform/dry-run)\", t)\n  return nil\n}","preventionTips":["Use the AWS API target for operations that mutate cloud state.","Don't invoke task.Delete directly in tests with mock targets; use AWSAPITarget or skip.","Expect terraform target to only plan, not delete."],"tags":["kops","type-assertion","autoscaling","internal"],"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-12T12:17:11.808Z"}