can1357/oh-my-pi · error · Error

Too many redirects (> ${MAX_REDIRECT_HOPS}) fetching ${url}

Error message

Too many redirects (> ${MAX_REDIRECT_HOPS}) fetching ${url}

What it means

mcpFetch performs manual redirect handling for origin-locked MCP servers so configured headers (auth tokens) are not leaked on cross-origin hops. Each redirect hop re-evaluates the origin; after exceeding MAX_REDIRECT_HOPS (5) it gives up and throws this Error instead of looping forever.

Source

Thrown at packages/coding-agent/src/mcp/transports/header-policy.ts:122

	}

	const configuredOrigin = new URL(url).origin;
	let currentUrl = url;
	for (let hop = 0; hop <= MAX_REDIRECT_HOPS; hop++) {
		const attachConfigured = new URL(currentUrl).origin === configuredOrigin;
		const headers = mergeMCPHeaders(attachConfigured ? sources : { generated: sources.generated });
		const response = await fetch(currentUrl, { ...init, headers, redirect: "manual" });
		if (!REDIRECT_STATUSES[response.status]) return response;

		const location = response.headers.get("Location");
		if (!location) return response;
		await response.body?.cancel();
		if (init.method !== "GET" && response.status !== 307 && response.status !== 308) {
			throw new Error(`HTTP ${response.status}: server redirected a ${init.method} request; refusing to follow`);
		}
		currentUrl = new URL(location, currentUrl).href;
	}
	throw new Error(`Too many redirects (> ${MAX_REDIRECT_HOPS}) fetching ${url}`);
}

View on GitHub (pinned to 9690622007)

Solutions

  1. Verify the MCP URL is the final endpoint, not a redirector — fix the configured URL to point directly at the MCP server
  2. Check the server's redirect chain with `curl -sIL <url>` and fix the loop (usually http→https or trailing-slash misconfiguration on the server)
  3. If the redirect is intentional and ends at the same origin, disable origin locking so platform fetch handles redirects natively
  4. Reduce intermediate proxies/load-balancer hops that each issue a redirect

Example fix

// before
const transport = new HttpTransport({ url: "http://mcp.example.com/mcp" }); // redirects to https://mcp.example.com/mcp/ ... chain exceeds 5 hops
// after
const transport = new HttpTransport({ url: "https://mcp.example.com/mcp/" }); // final URL, no redirect chain
Defensive patterns

Strategy: validation

Validate before calling

// Check the endpoint's redirect behavior before configuring it:
const res = await fetch(url, { redirect: "manual" });
if ([301,302,303,307,308].includes(res.status)) console.warn("endpoint redirects; use the final URL", res.headers.get("Location"));

Try / catch

try {
  const res = await mcpFetch(url, init, sources, true);
} catch (err) {
  if (err instanceof Error && err.message.startsWith("Too many redirects")) {
    // fall back to the platform fetch or surface a config error to the user
  } else throw err;
}

Prevention

When it happens

Trigger: A request to an origin-locked MCP endpoint receives a chain of 301/302/303/307/308 responses with Location headers whose cumulative length exceeds 5 hops — typically a redirect loop or an excessively long redirect chain.

Common situations: Misconfigured MCP server URLs (e.g. pointing at a load balancer that bounces between http and https, or between hosts with trailing-slash mismatch); a server whose auth endpoint redirects to itself; proxies that keep redirecting to login pages.

Related errors


AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31). Data as JSON: /api/errors/f40dccfec5cbd8c7. Report an issue: GitHub.