Hmbown/CodeWhale · error · NonRetryableError

too many redirects starting at

Error message

too many redirects starting at ${url}

What it means

The installer's download loop follows redirect responses with a bounded iteration count; `resolveDownload` throws this NonRetryableError when the starting URL still has not yielded a final (non-redirect) response after the limit. It protects against redirect loops or endless redirect chains on a misconfigured release mirror.

Solutions

  1. Open the failing URL in a browser/curl and inspect where the redirect chain leads; fix CODEWHALE_RELEASE_BASE_URL to point directly at the artifact host.
  2. Retry the install later if the mirror is misbehaving or mid-migration.
  3. Switch to the default release source by unsetting CODEWHALE_RELEASE_BASE_URL / CODEWHALE_USE_CNB_MIRROR.
  4. Clear an http->https loop by using the final https URL explicitly.

Example fix

// before
CODEWHALE_RELEASE_BASE_URL=http://old-mirror.example.com/codewhale
// after (point directly at final host)
CODEWHALE_RELEASE_BASE_URL=https://releases.example.com/codewhale
Defensive patterns

Strategy: fallback

Try / catch

try {
  await download(url);
} catch (err) {
  if (err.message.startsWith('too many redirects')) {
    // fix mirror URL or fall back to the default release source
    process.env.CODEWHALE_RELEASE_BASE_URL = DEFAULT_BASE_URL;
  } else throw err;
}

Prevention

When it happens

Trigger: Fetching an asset/manifest URL whose server responds with a redirect chain longer than the allowed maximum, or two URLs redirecting to each other in a loop.

Common situations: CODEWHALE_RELEASE_BASE_URL pointed at a mirror that bounces between http/https or adds trailing-slash redirects forever; a corporate proxy rewriting redirects; a mirror serving 302s to a login page in a loop.

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/e2dfcb98ece5d677. Report an issue: GitHub.

Appendix: source

Thrown at npm/codewhale/scripts/install.js:985

// Public download primitives (now retry + progress aware)
// ────────────────────────────────────────────────────────────────────────────

async function followRedirects(url, opts = {}) {
  const maxRedirects = 10;
  let current = url;
  for (let hop = 0; hop < maxRedirects; hop++) {
    const result = await httpRequest(current, opts);
    if (result.redirect) {
      try {
        current = new URL(result.redirect, current).toString();
      } catch {
        current = result.redirect;
      }
      continue;
    }
    return result;
  }
  throw new NonRetryableError(`too many redirects starting at ${url}`);
}

function streamToFile(response, destination, progress, signal) {
  return new Promise((resolve, reject) => {
    const sink = createWriteStream(destination);
    let done = false;
    const onAbort = () => {
      try {
        response.destroy();
      } catch {
        // ignore
      }
      finish(abortError());
    };
    const finish = (err) => {
      if (done) return;
      done = true;
      if (signal) {

View on GitHub (pinned to 433685b202)