iOfficeAI/AionUi · error · Error

update.errors.tooManyRedirects

update.errors.tooManyRedirects

Error message

update.errors.tooManyRedirects

What it means

Thrown by fetchWithAllowlistedRedirects when the redirect loop exhausts its maximum iteration count — the fetch kept receiving 3xx responses (each with a valid Location) and never returned a final non-redirect response. This guards against redirect cycles.

Source

Thrown at packages/desktop/src/process/bridge/updateBridge.ts:312

      redirect: 'manual',
      headers: {
        'User-Agent': DEFAULT_USER_AGENT,
      },
    });

    if (res.status >= 300 && res.status < 400) {
      const location = res.headers.get('location');
      if (!location) {
        throw new Error((await getI18n()).t('update.errors.redirectNoLocation'));
      }
      current = new URL(location, current).toString();
      continue;
    }

    return res;
  }

  throw new Error((await getI18n()).t('update.errors.tooManyRedirects'));
};

const fetchGitHubReleases = async (repo: string, timeoutMs = 30000): Promise<GitHubReleaseApi[]> => {
  const url = `https://api.github.com/repos/${repo}/releases`;

  // 添加超时控制,防止网络问题导致无限等待 / Add timeout to prevent infinite wait on network issues
  const controller = new AbortController();
  const timeoutId = setTimeout(() => controller.abort(), timeoutMs);

  try {
    const res = await fetch(url, {
      headers: {
        Accept: 'application/vnd.github+json',
        'User-Agent': DEFAULT_USER_AGENT,
      },
      signal: controller.signal,
    });

View on GitHub (pinned to 711aa0550e)

Solutions

  1. curl -IL the URL to trace the redirect chain and find the loop
  2. Fix the server/proxy redirect rules (host canonicalization, trailing-slash handling)
  3. Ensure any auth/cookie the endpoint needs is sent so it stops bouncing
  4. Bypass the redirecting layer and point the updater at the final artifact URL

Example fix

# before
url = https://cdn.example.com/latest  # loops cdn <-> auth
# after
url = https://github.com/owner/repo/releases/download/v1.2.0/app.dmg
Defensive patterns

Strategy: retry

Try / catch

try {
  await fetchWithAllowlistedRedirects(url, signal);
} catch (err) {
  if (err instanceof Error && err.message.includes('tooManyRedirects')) {
    await backoff(); await fetchWithAllowlistedRedirects(url, signal); // one retry
  } else throw err;
}

Prevention

When it happens

Trigger: An update URL involved in a redirect loop (A -> B -> A) or an extremely long chain exceeding the loop cap; also a server that always answers 3xx regardless of request.

Common situations: CDN misroutes causing A/B bounce; auth cookies not forwarded so the server keeps redirecting to login; http->https plus trailing-slash redirects stacking into a cycle behind a proxy; stale presigned URLs that redirect forever.

Related errors


AI-assisted analysis of iOfficeAI/AionUi@711aa0550e (2026-08-28). Data as JSON: /api/errors/906a65a668e802f2. Report an issue: GitHub.