anomalyco/sst · error

failed to delete script: HTTP %d %s

Error message

failed to delete script: HTTP %d %s

What it means

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.

Source

Thrown at pkg/server/resource/cloudflare-worker-script.go:516

func (r *WorkerScript) handleDelete(input *WorkerScriptOutputs) error {
	url := fmt.Sprintf("https://api.cloudflare.com/client/v4/accounts/%s/workers/scripts/%s", input.AccountId, input.ScriptName)

	req, err := http.NewRequest("DELETE", url, nil)
	if err != nil {
		return err
	}
	req.Header.Set("Authorization", "Bearer "+input.ApiToken)

	client := &http.Client{Timeout: 30 * time.Second}
	resp, err := client.Do(req)
	if err != nil {
		return err
	}
	defer resp.Body.Close()

	if resp.StatusCode != http.StatusOK {
		responseBody, _ := io.ReadAll(resp.Body)
		return fmt.Errorf("failed to delete script: HTTP %d %s", resp.StatusCode, string(responseBody))
	}
	return nil
}

View on GitHub (pinned to a0bd20f762)

Solutions

  1. Read the response body in the error for Cloudflare's error codes
  2. On 404, the script is already gone — remove it from state or ignore the destroy failure
  3. Verify the apiToken still has Workers Scripts:Edit permission
  4. Retry on 429/5xx after a delay

Example fix

// token scoped read-only -> 403 on delete
// before: token permission "Workers Scripts:Read"
// after: token permission "Workers Scripts:Edit"
Defensive patterns

Strategy: retry

Validate before calling

if output.ScriptName == "" || output.AccountId == "" { return errors.New("outputs missing account/script name; cannot delete") }
// optionally: GET the script first and skip delete on 404

Try / catch

if strings.Contains(err.Error(), "HTTP 404") {
    log.Println("script already deleted; treating destroy as success")
    return nil
}
if strings.Contains(err.Error(), "HTTP 429") || strings.Contains(err.Error(), "HTTP 5") {
    // retry with exponential backoff
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of anomalyco/sst@a0bd20f762 (2026-08-30). Data as JSON: /api/errors/284c71fca3f81bae. Report an issue: GitHub.