From 6bbef2cb52daac78dfe6cf7109545a6e3d648b31 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gerg=C5=91=20T=C3=B6rcsv=C3=A1ri?= Date: Wed, 29 Jul 2026 09:11:45 +0200 Subject: [PATCH] fix(deploy): r2 getJSON must not read transient API errors as missing objects MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A CF API 502 on the manifest.json probe made publish-libs misdetect an already-published tag as unpublished and start a full republish (byte-identical immutable content, so harmless — but ~30 min of redundant uploads before a second 502 killed it). Only wrangler's definitive missing-object error now reads as absent; anything else throws. Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_011CC8aAnUUHcnHy3QCJtUwb --- scripts/deploy/lib/cdn-store.mjs | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/scripts/deploy/lib/cdn-store.mjs b/scripts/deploy/lib/cdn-store.mjs index 9f55998..02b6950 100644 --- a/scripts/deploy/lib/cdn-store.mjs +++ b/scripts/deploy/lib/cdn-store.mjs @@ -135,8 +135,17 @@ export function r2Driver({ bucket, remote }) { run(["r2", "object", "get", `${bucket}/${key}`, "--file", dest, ...flags], { quiet: true, }); - } catch { - return null; // not found / error → absent (expected on first publish) + } catch (e) { + // ONLY a definitive "no such object" reads as absent. Any other failure + // (CF API 5xx, auth, network) must THROW: publishers branch on these + // probes — publish-libs once misread a transient 502 on manifest.json + // as "tag not published" and started a full republish of an existing + // immutable tag (harmless bytes-wise, ~30 min wasted). + const msg = `${e?.stderr ?? ""}${e?.stdout ?? ""}${e?.message ?? ""}`; + if (/does not exist|no such object|not found|404/i.test(msg)) return null; + throw new Error( + `r2 get ${bucket}/${key} failed (NOT a missing-object miss): ${msg.slice(0, 400)}`, + ); } try { return JSON.parse(readFileSync(dest, "utf8"));