Webhooks send empty body to Vercel API

I’m using Moralis webhooks to write my cloud functions and am deploying them to Vercel.

When I run my server locally (next dev) and point the Moralis webhooks to it by using ngrok, I see the body and everything works. But, when the webhooks are pointing to the actual deployed API in Vercel, the body is always empty in the request object.

Somebody was having the exact same issue but when using Moralis.cloud.httpRequest to call their Vercel endpoint: https://discord.com/channels/819584798443569182/819584798443569185/872549645367263252. This seems like the same scenario but for webhooks.

Can you paste a complete request with the http headers of what you receive on your local server from webhooks (when it works ok)?
Just to see how that content-length was set there. As you assume that it is a problem how web hooks set content length header field.

Here it is:

{
  req: IncomingMessage {
    _readableState: ReadableState {
      objectMode: false,
      highWaterMark: 16384,
      buffer: BufferList { head: null, tail: null, length: 0 },
      length: 0,
      pipes: [],
      flowing: true,
      ended: true,
      endEmitted: true,
      reading: false,
      sync: true,
      needReadable: false,
      emittedReadable: false,
      readableListening: false,
      resumeScheduled: false,
      errorEmitted: false,
      emitClose: true,
      autoDestroy: false,
      destroyed: false,
      errored: null,
      closed: false,
      closeEmitted: false,
      defaultEncoding: 'utf8',
      awaitDrainWriters: null,
      multiAwaitDrain: false,
      readingMore: true,
      decoder: null,
      encoding: null,
      [Symbol(kPaused)]: false
    },
    _events: [Object: null prototype] { end: [Function: clearRequestTimeout] },
    _eventsCount: 1,
    _maxListeners: undefined,
    socket: Socket {
      connecting: false,
      _hadError: false,
      _parent: null,
      _host: null,
      _readableState: [ReadableState],
      _events: [Object: null prototype],
      _eventsCount: 8,
      _maxListeners: undefined,
      _writableState: [WritableState],
      allowHalfOpen: true,
      _sockname: null,
      _pendingData: null,
      _pendingEncoding: '',
      server: [Server],
      _server: [Server],
      parser: [HTTPParser],
      on: [Function: socketListenerWrap],
      addListener: [Function: socketListenerWrap],
      prependListener: [Function: socketListenerWrap],
      _paused: false,
      _httpMessage: [ServerResponse],
      [Symbol(async_id_symbol)]: 64633,
      [Symbol(kHandle)]: [TCP],
      [Symbol(kSetNoDelay)]: false,
      [Symbol(lastWriteQueueSize)]: 0,
      [Symbol(timeout)]: null,
      [Symbol(kBuffer)]: null,
      [Symbol(kBufferCb)]: null,
      [Symbol(kBufferGen)]: null,
      [Symbol(kCapture)]: false,
      [Symbol(kBytesRead)]: 0,
      [Symbol(kBytesWritten)]: 0,
      [Symbol(RequestTimeout)]: undefined
    },
    httpVersionMajor: 1,
    httpVersionMinor: 1,
    httpVersion: '1.1',
    complete: true,
    headers: {
      host: 'redacted',
      'transfer-encoding': 'chunked',
      'content-type': 'application/json',
      'x-forwarded-for': redacted',
      'x-forwarded-proto': 'https',
      'accept-encoding': 'gzip'
    },
    rawHeaders: [
      'Host',
      'redacted',
      'Transfer-Encoding',
      'chunked',
      'Content-Type',
      'application/json',
      'X-Forwarded-For',
      'redacted',
      'X-Forwarded-Proto',
      'https',
      'Accept-Encoding',
      'gzip'
    ],
    trailers: {},
    rawTrailers: [],
    aborted: false,
    upgrade: false,
    url: '/api/user/edit',
    method: 'POST',
    statusCode: null,
    statusMessage: null,
    client: Socket {
      connecting: false,
      _hadError: false,
      _parent: null,
      _host: null,
      _readableState: [ReadableState],
      _events: [Object: null prototype],
      _eventsCount: 8,
      _maxListeners: undefined,
      _writableState: [WritableState],
      allowHalfOpen: true,
      _sockname: null,
      _pendingData: null,
      _pendingEncoding: '',
      server: [Server],
      _server: [Server],
      parser: [HTTPParser],
      on: [Function: socketListenerWrap],
      addListener: [Function: socketListenerWrap],
      prependListener: [Function: socketListenerWrap],
      _paused: false,
      _httpMessage: [ServerResponse],
      [Symbol(async_id_symbol)]: 64633,
      [Symbol(kHandle)]: [TCP],
      [Symbol(kSetNoDelay)]: false,
      [Symbol(lastWriteQueueSize)]: 0,
      [Symbol(timeout)]: null,
      [Symbol(kBuffer)]: null,
      [Symbol(kBufferCb)]: null,
      [Symbol(kBufferGen)]: null,
      [Symbol(kCapture)]: false,
      [Symbol(kBytesRead)]: 0,
      [Symbol(kBytesWritten)]: 0,
      [Symbol(RequestTimeout)]: undefined
    },
    _consuming: false,
    _dumped: false,
    cookies: [Getter/Setter],
    __NEXT_INIT_QUERY: {},
    __nextHadTrailingSlash: undefined,
    query: {},
    previewData: [Getter/Setter],
    preview: [Getter/Setter],
    body: {
      params: [Object],
      master: false,
      user: [Object],
      installationId: 'redacted',
      log: [Object],
      headers: [Object],
      ip: 'redacted',
      functionName: 'editProfile',
      context: {}
    },
    [Symbol(kCapture)]: false,
    [Symbol(RequestTimeout)]: undefined
  }
}

And to be clear, the content-length does not seem to be present for this request either, but it seems like my local server doesn’t care and still parses the body correctly. It seems that the issue is only when it’s actually deployed in Vercel where the content-length starts coming into play.

Were you guys able to look into this today? Our team is basically blocked for promoting to our staging and prod envs because of this. Right now we’re just able to develop locally.

Thanks!

@cryptokid shameless ping. Sorry, we’re just blocked on promotions with this issue. Is there a way that you guys can check what headers the webhook calls attach to the requests they make?

Maybe the content-length is not being passed.

1 Like