{"record":{"id":"e46c0af627506e76","repo":"kubernetes/kops","slug":"failed-to-convert-droplet-id-to-int-s","errorCode":null,"errorMessage":"failed to convert droplet ID to int: %s","messagePattern":"failed to convert droplet ID to int: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/resources/digitalocean/resources.go","lineNumber":258,"sourceCode":"\n\t\t\tvar blocks []string\n\t\t\tfor _, dropletID := range lb.DropletIDs {\n\t\t\t\tblocks = append(blocks, \"droplet:\"+strconv.Itoa(dropletID))\n\t\t\t}\n\n\t\t\tresourceTracker.Blocks = blocks\n\t\t\tresourceTrackers = append(resourceTrackers, resourceTracker)\n\t\t}\n\t}\n\n\treturn resourceTrackers, nil\n}\n\nfunc deleteDroplet(cloud fi.Cloud, t *resources.Resource) error {\n\tc := cloud.(do.DOCloud)\n\tdropletID, err := strconv.Atoi(t.ID)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to convert droplet ID to int: %s\", err)\n\t}\n\n\t_, err = c.DropletsService().Delete(context.TODO(), dropletID)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to delete droplet: %d, err: %s\", dropletID, err)\n\t}\n\n\treturn nil\n}\n\nfunc deleteVPC(cloud fi.Cloud, t *resources.Resource) error {\n\tc := cloud.(do.DOCloud)\n\t_, err := c.VPCsService().Delete(context.TODO(), t.ID)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to delete VPC %s (ID %s): %s\", t.Name, t.ID, err)\n\t}\n\n\treturn nil","sourceCodeStart":240,"sourceCodeEnd":276,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/pkg/resources/digitalocean/resources.go#L240-L276","documentation":"deleteDroplet parses the resource tracker's t.ID string as an integer droplet ID via strconv.Atoi; failure is wrapped here. DO droplet IDs are numeric, so a non-numeric ID means the tracker was built with wrong data.","triggerScenarios":"t.ID is not a valid base-10 integer, e.g. empty string, a resource whose ID field was populated with a name/slug instead of a DO numeric ID.","commonSituations":"Corrupted or hand-edited cluster state/manifest; a bug populating Resource.ID for droplets; running kops against state referencing non-DO resources.","solutions":["Inspect the Resource ID in the source state; it must be the numeric DO droplet ID","Re-fetch state from the cluster spec rather than hand-edited manifests","Report/fix the code path that set a non-numeric ID","Delete the droplet manually via doctl compute droplet delete <id> if kOps state is unrecoverable"],"exampleFix":"// before\nt.ID = \"web-1\"  // slug, not numeric\n// after\nt.ID = \"31644451\"  // numeric DO droplet ID","handlingStrategy":"validation","validationCode":"if n, err := strconv.Atoi(t.ID); err != nil || n <= 0 {\n\treturn fmt.Errorf(\"droplet ID %q is not a valid numeric DO droplet ID\", t.ID)\n}","typeGuard":"func isNumericID(id string) bool {\n\t_, err := strconv.Atoi(id)\n\treturn err == nil\n}","tryCatchPattern":"dropletID, err := strconv.Atoi(t.ID)\nif err != nil {\n\treturn fmt.Errorf(\"failed to convert droplet ID to int: %w\", err)\n}","preventionTips":["Never hand-edit kops state files that hold resource IDs","Store raw numeric DO IDs in resource trackers, not names/slugs","Validate state after import/migration"],"tags":["digitalocean","parsing","type-conversion"],"backgroundTag":"strconv-parse-error","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"}