mastra-ai/mastra · error · PlatformApiError

Platform API request did not return a redirect.

Error message

Platform API request did not return a redirect.

What it means

PlatformApiError thrown by PlatformApiClient.requestRedirect (api-client.ts:95) when an HTTP call expected to return a 3xx redirect (fetched with redirect: 'manual') instead returned a successful non-redirect response. The client uses requestRedirect for endpoints whose success contract is a Location header (e.g. OAuth/browser redirect flows), so a 2xx response with no Location header is treated as a protocol violation rather than a result. The response's real status is preserved on the error.

Source

Thrown at mastracode/factory/src/integrations/platform/api-client.ts:95

    const response = await this.#send(method, path, undefined, options, 'manual');
    if (response.status >= 300 && response.status < 400) {
      const location = response.headers.get('location');
      if (location) return location;
    }
    if (!response.ok) {
      const message = redact(await extractError(response), this.#accessToken);
      const retryAfterSeconds = parseRetryAfter(response.headers.get('retry-after'));
      logPlatformError('Platform API redirect request failed', {
        method,
        path,
        status: response.status,
        retryAfterSeconds,
        message,
      });
      throw new PlatformApiError(message, response.status, retryAfterSeconds);
    }
    logPlatformError('Platform API request did not return a redirect', { method, path, status: response.status });
    throw new PlatformApiError('Platform API request did not return a redirect.', response.status);
  }

  async #send(
    method: string,
    path: string,
    body?: unknown,
    options?: { signal?: AbortSignal; actingUserId?: string },
    redirect?: RequestInit['redirect'],
  ): Promise<Response> {
    const headers: Record<string, string> = {
      accept: 'application/json',
      authorization: `Bearer ${this.#accessToken}`,
    };
    // Acting end-user for platform GitHub writes: the platform resolves this
    // user's GitHub OAuth connection (org-scoped) so issues/PRs are authored
    // by the human instead of the App bot. Ignored by older platforms.
    if (options?.actingUserId) {
      headers['x-acting-user-id'] = options.actingUserId;

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Verify the path passed to requestRedirect is the platform endpoint that issues redirects (e.g. OAuth authorize/install URL), not a JSON API route.
  2. Check that the platform server version supports the redirect endpoint; upgrade platform or client if there is a version mismatch.
  3. Inspect intermediate proxies/gateways that may convert 3xx into 200 and disable redirect rewriting for this route.
  4. If a JSON response is actually expected, use client.request() instead of requestRedirect().
  5. Catch PlatformApiError and inspect error.status to distinguish a 200-with-no-redirect from an actual HTTP failure.

Example fix

// before: treating any endpoint as a redirect endpoint
const url = await client.requestRedirect('POST', '/api/agents');

// after: use the redirect endpoint for redirect flows, request() for JSON
const url = await client.requestRedirect('POST', `/api/github/installations/${installationId}/install-url`);
Defensive patterns

Strategy: try-catch

Validate before calling

// No client-side pre-check possible; ensure the path is the documented redirect endpoint
const REDIRECT_ENDPOINTS = ['/github/install-url', '/oauth/authorize'];
if (!REDIRECT_ENDPOINTS.some((e) => path.startsWith(e))) {
  throw new Error(`${path} is not a redirect endpoint; use client.request()`);
}

Type guard

function isRedirectStatus(status: number): boolean {
  return status >= 300 && status < 400;
}

Try / catch

try {
  const location = await client.requestRedirect('GET', path);
} catch (err) {
  if (err instanceof PlatformApiError && err.status >= 200 && err.status < 300) {
    // Endpoint returned 2xx without a Location header: wrong endpoint or
    // server/proxy stripped the redirect. Fall back or surface a clear message.
  }
  throw err;
}

Prevention

When it happens

Trigger: Calling client.requestRedirect(method, path) where the server responds 200/204 (or any 2xx) without a 3xx status or Location header — e.g. the endpoint was changed to return JSON instead of redirecting, a proxy/gateway strips the 3xx, or the wrong path is used so a normal endpoint answers instead of the redirect endpoint.

Common situations: Platform/API version mismatch where the redirect endpoint no longer exists and a default handler responds 200; an auth or GitHub App installation URL flow pointed at a JSON API route; a corporate proxy or load balancer rewriting redirects into 200 responses; typos in the path passed to requestRedirect.

Related errors


AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30). Data as JSON: /api/errors/0ed8abffc55fdd1d. Report an issue: GitHub.