From c61a9c6085175cd0b0fa18429a1df4397b26b8fa Mon Sep 17 00:00:00 2001 From: A <258483684+la14-1@users.noreply.github.com> Date: Mon, 2 Mar 2026 05:36:42 -0800 Subject: [PATCH] fix(hetzner): throw on non-2xx responses to prevent silent failures (#2105) hetznerApi() was returning raw response text on non-2xx final attempts instead of throwing, identical to the bug fixed in daytonaApi() by PR #2102. Impact: a 5xx when fetching SSH keys caused createServer() to receive null from parseJsonObj(), fall back to an empty SSH key list, and provision a server the user cannot SSH into -- with no error or warning. Fix matches the pattern from lightsailRest() (AWS) and PR #2102 (Daytona): throw with the HTTP status code after retries exhaust on any !resp.ok response. Agent: code-health Co-authored-by: B <6723574+louisgv@users.noreply.github.com> Co-authored-by: Claude Sonnet 4.5 --- packages/cli/src/hetzner/hetzner.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/cli/src/hetzner/hetzner.ts b/packages/cli/src/hetzner/hetzner.ts index be672d5c..f7fb0995 100644 --- a/packages/cli/src/hetzner/hetzner.ts +++ b/packages/cli/src/hetzner/hetzner.ts @@ -76,6 +76,9 @@ async function hetznerApi(method: string, endpoint: string, body?: string, maxRe interval = Math.min(interval * 2, 30); continue; } + if (!resp.ok) { + throw new Error(`Hetzner API error (HTTP ${resp.status}): ${text.slice(0, 200)}`); + } return text; } catch (err) { if (attempt >= maxRetries) {