error: 'unsupported_grant_type', (durng token exchange)

I am attempting to do token exchange with an auth code, from an Express.js API. I am getting back an error object:

error: 'unsupported_grant_type',
  error_description: 'The supported grant types are `authorization_code` and `refresh_token`.'

This is the object I send as the post request body (stringified). Is there a mistake or omission somewhere?

tokenRequestBody {
  grant_type: 'authorization_code',
  client_id: '11885REMOVED',
  client_secret: 'b2d0b11a1REMOVED',
  redirect_uri: '',
  code: '1/111920289783REMOVED'

Here is the surrounding context:

router.get('/authCode', async (req: Request, res: Response) => {
  const tokenExchangeEndpoint = '';

  const tokenRequestBody: IAuthCodeRequest = {
    grant_type: 'authorization_code',
    client_id: process.env.ASANA_CLIENT_ID!,
    client_secret: process.env.ASANA_CLIENT_SECRET!,
    redirect_uri: process.env.ASANA_HTTPS_REDIRECT_URL!,
    code: req.query.code as string,

  // the object shown above
  console.log('tokenRequestBody', tokenRequestBody);

  try {
    const response = await fetch(tokenExchangeEndpoint, {
      method: 'post',
      // mode: 'cors',
      headers: {
        'content-type': 'application/json',
      body: JSON.stringify(tokenRequestBody),

    const tokenObject: ITokenResponseBody = await response.json();

    // the error object prints
    console.log('tokenObject', tokenObject);