Foundry376/Mailspring · error

OAuth Code exchange returned ${resp.status} ${resp.statusTex

Error message

OAuth Code exchange returned ${resp.status} ${resp.statusText}: ${JSON.stringify(json)}

What it means

Helper guard in fetchPostWithFormBody during onboarding: the OAuth token endpoint (Google or Microsoft) returned a non-2xx status to the application/x-www-form-urlencoded POST. The body JSON is embedded so the failure reason (invalid_grant, bad client_secret, expired code) is visible; commonly caused by reusing an already-consumed authorization code or a clock-skewed/redirect_uri mismatch.

Source

Thrown at app/internal_packages/onboarding/lib/onboarding-helpers.ts:63

  };

  const idString = `${emailAddress}${JSON.stringify(settingsThatCouldChangeMailContents)}`;
  return crypto.createHash('sha256').update(idString, 'utf8').digest('hex').substr(0, 8);
}

async function fetchPostWithFormBody<T>(url: string, body: { [key: string]: string }) {
  const resp = await fetch(url, {
    method: 'POST',
    body: Object.entries(body)
      .map(([key, value]) => encodeURIComponent(key) + '=' + encodeURIComponent(value))
      .join('&'),
    headers: {
      'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8',
    },
  });
  const json = ((await resp.json()) || {}) as T;
  if (!resp.ok) {
    throw new Error(
      `OAuth Code exchange returned ${resp.status} ${resp.statusText}: ${JSON.stringify(json)}`
    );
  }
  return json;
}

function mxRecordsForDomain(domain) {
  return new Promise<string[]>((resolve, reject) => {
    // timeout here is annoyingly long - 30s?
    dns.resolveMx(domain, (err, addresses) => {
      if (err) {
        resolve([]);
      } else {
        resolve(addresses.map((a) => a.exchange.toLowerCase()));
      }
    });
  });
}

View on GitHub (pinned to 648c685d60)

Solutions

  1. Restart the OAuth flow to obtain a fresh authorization code — codes are single-use and short-lived
  2. Verify redirect_uri and client credentials exactly match the provider app configuration
  3. Inspect the embedded JSON body for the OAuth error field (e.g. invalid_grant) to pinpoint the cause
Defensive patterns

Strategy: try-catch

When it happens

Trigger: Thrown at app/internal_packages/onboarding/lib/onboarding-helpers.ts:63 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of Foundry376/Mailspring@648c685d60 (2026-09-03). Data as JSON: /api/errors/4921d0b2d55d6d0b. Report an issue: GitHub.