{"record":{"id":"284c71fca3f81bae","repo":"anomalyco/sst","slug":"failed-to-delete-script-http-d-s","errorCode":null,"errorMessage":"failed to delete script: HTTP %d %s","messagePattern":"failed to delete script: HTTP (.+?) (.+?)","errorType":"http","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/server/resource/cloudflare-worker-script.go","lineNumber":516,"sourceCode":"func (r *WorkerScript) handleDelete(input *WorkerScriptOutputs) error {\n\turl := fmt.Sprintf(\"https://api.cloudflare.com/client/v4/accounts/%s/workers/scripts/%s\", input.AccountId, input.ScriptName)\n\n\treq, err := http.NewRequest(\"DELETE\", url, nil)\n\tif err != nil {\n\t\treturn err\n\t}\n\treq.Header.Set(\"Authorization\", \"Bearer \"+input.ApiToken)\n\n\tclient := &http.Client{Timeout: 30 * time.Second}\n\tresp, err := client.Do(req)\n\tif err != nil {\n\t\treturn err\n\t}\n\tdefer resp.Body.Close()\n\n\tif resp.StatusCode != http.StatusOK {\n\t\tresponseBody, _ := io.ReadAll(resp.Body)\n\t\treturn fmt.Errorf(\"failed to delete script: HTTP %d %s\", resp.StatusCode, string(responseBody))\n\t}\n\treturn nil\n}\n","sourceCodeStart":498,"sourceCodeEnd":520,"githubUrl":"https://github.com/anomalyco/sst/blob/a0bd20f762883e72a35caccb4896c42ce5b3f707/pkg/server/resource/cloudflare-worker-script.go#L498-L520","documentation":"This error is returned when the Cloudflare DELETE /accounts/{id}/workers/scripts/{name} call in handleDelete responds with any non-200 status. The error includes the HTTP status and Cloudflare's response body so the underlying API error codes are visible. Raised during Delete of the WorkerScript resource.","triggerScenarios":"resp.StatusCode != 200 on the DELETE request — typically 403 (token lacks delete permission), 404 (script already gone or wrong name/account), or 429/5xx from Cloudflare.","commonSituations":"Destroying a stack with a revoked/expired API token; script already deleted out-of-band (404); account ID in outputs no longer valid; Cloudflare rate limiting or outage.","solutions":["Read the response body in the error for Cloudflare's error codes","On 404, the script is already gone — remove it from state or ignore the destroy failure","Verify the apiToken still has Workers Scripts:Edit permission","Retry on 429/5xx after a delay"],"exampleFix":"// token scoped read-only -> 403 on delete\n// before: token permission \"Workers Scripts:Read\"\n// after: token permission \"Workers Scripts:Edit\"","handlingStrategy":"retry","validationCode":"if output.ScriptName == \"\" || output.AccountId == \"\" { return errors.New(\"outputs missing account/script name; cannot delete\") }\n// optionally: GET the script first and skip delete on 404","typeGuard":null,"tryCatchPattern":"if strings.Contains(err.Error(), \"HTTP 404\") {\n    log.Println(\"script already deleted; treating destroy as success\")\n    return nil\n}\nif strings.Contains(err.Error(), \"HTTP 429\") || strings.Contains(err.Error(), \"HTTP 5\") {\n    // retry with exponential backoff\n}","preventionTips":["Ensure the API token used for destroy retains Workers Scripts:Edit","Treat 404 during destroy as idempotent success","Rate-limit concurrent deletes against the Cloudflare API"],"tags":["cloudflare","http","delete","workers","api-error"],"backgroundTag":"http-non-2xx-response","analyzedSha":"a0bd20f762883e72a35caccb4896c42ce5b3f707","analyzedAt":"2026-08-30T11:26:00.383Z","schemaVersion":2},"datasetVersion":"2026-08-30T13:17:10.514Z"}