Hmbown/CodeWhale · error · Error

returned HTTP ( )

Error message

${label} returned HTTP ${status} (${url})

What it means

verifyAsset checks a release asset URL responds successfully. After trying HEAD (falling back to GET on 403/405), any status outside 2xx/3xx means the asset is missing, private, or the release is broken, so it throws with the label and URL.

Solutions

  1. Confirm the GitHub release exists, is published (not draft), and all assets are uploaded
  2. Check the asset naming/URL matches what the script expects for this version/arch
  3. Ensure GITHUB_TOKEN is set if the repo is private
  4. Re-upload missing assets or re-run the release workflow
Defensive patterns

Strategy: retry

Validate before calling

const res = await fetch(url, { method: "HEAD" });
if (!(res.status >= 200 && res.status < 400)) {
  throw new Error(`Asset unavailable: ${url} -> ${res.status}; check the release is published with assets uploaded`);
}

Try / catch

try { await verifyAsset(url, label); } catch (e) { if (/returned HTTP (404|403)/.test(e.message)) { console.error("Release draft or assets missing; re-run release upload"); } throw e; }

Prevention

When it happens

Trigger: run() calls verifyAsset for each expected release asset (checksums, binaries) and the server returns e.g. 404 (asset not uploaded), 401 (private repo), or 5xx.

Common situations: Release published before assets finished uploading; tag exists but release is draft; asset renamed so the expected URL 404s; token missing for private repo.

Understand the failure class

Background: "API error: {status}" and "HTTP 401/403/404/429/5xx" errors: non-2xx HTTP responses explained — this error's family across 27 libraries.

Related errors


AI-assisted analysis of Hmbown/CodeWhale@433685b202 (2026-09-15). Data as JSON: /api/errors/902948e9184deebf. Report an issue: GitHub.

Appendix: source

Thrown at npm/codewhale/scripts/verify-release-assets.js:102

          const next = new URL(location, url).toString();
          resolve(requestStatus(next, method, redirects + 1));
          return;
        }
        resolve(status);
      },
    );
    req.on("error", reject);
    req.end();
  });
}

async function verifyAsset(url, label) {
  let status = await requestStatus(url, "HEAD");
  if (status === 403 || status === 405) {
    status = await requestStatus(url, "GET");
  }
  if (status < 200 || status >= 400) {
    throw new Error(`${label} returned HTTP ${status} (${url})`);
  }
}

async function downloadText(url, redirects = 0) {
  if (redirects > 10) {
    throw new Error(`Too many redirects while downloading ${url}`);
  }
  const client = url.startsWith("https:") ? https : http;
  return new Promise((resolve, reject) => {
    client
      .get(
        url,
        {
          headers: {
            "User-Agent": "codewhale-npm-release-check",
          },
        },
        (res) => {

View on GitHub (pinned to 433685b202)