cli icon indicating copy to clipboard operation
cli copied to clipboard

Netlify Functions not receiving a body in local dev but works once deployed to Netlify

Open mclimb opened this issue 2 years ago • 4 comments

Describe the bug

When I submit a fetch in from my Next.js app in local development using netlify dev (local node version v17.4.0), the Netlify Function runs but the body in the event is always undefined. I expect it to be { url: "websiteUrl" }. When I deployed the function to Netlify it correctly found and parsed the body.

I noticed this occur on both background and regular functions.

I submitted more details about this issue here: https://answers.netlify.com/t/why-arent-my-netlify-functions-finding-a-body/74661

Steps to reproduce

  1. Run git clone [email protected]:mclimb/jamhack-personalized-demo.git (private repo, ask Mike Chirokas for access)
  2. Install npm packages
  3. netlify dev
  4. Go localhost:8888
  5. Submit to any function endpoint, for example, enter the website url as https://miro.com/ and click the color pallet button (this will try to get the colors on https://miro.com/) and should call the function getBrandColors which should take the url body

Configuration

No response

Environment

System:
    OS: macOS 12.5.1
    CPU: (8) arm64 Apple M1
    Memory: 756.27 MB / 16.00 GB
    Shell: 5.8.1 - /bin/zsh
  Binaries:
    Node: 17.4.0 - ~/.nvm/versions/node/v17.4.0/bin/node
    Yarn: 1.22.17 - ~/.nvm/versions/node/v17.4.0/bin/yarn
    npm: 8.3.1 - ~/.nvm/versions/node/v17.4.0/bin/npm
  npmGlobalPackages:
    netlify-cli: 11.5.1

mclimb avatar Sep 07 '22 13:09 mclimb

Getting the same error, also on a M1 Mac in dev mode.

Netlify-cli: netlify-cli/11.7.1 darwin-x64 node-v16.13.2

PhilBookst avatar Sep 11 '22 11:09 PhilBookst

Alright! Things I've tried to investigate if this has anything to do with next-runtime

  1. Removed all code from next-runtime that we're running in onPreDev - error still occurs (no body sent)
  2. Commented out the line in the cli that adds a plugin during dev (currently line 476 in src/commands/dev/dev.js:
      // cachedConfig.config.plugins = [...newPlugins, ...cachedConfig.config.plugins]

which still gives the same error - the next-runtime isn't being run during dev, but the body is still not being sent.

So this leads me to think it's something that is a bug in the cli, or at the very least something we're not doing in the next-runtime that we should be.

sarahetter avatar Sep 20 '22 17:09 sarahetter

I get the same body undefined when posting to function: netlify-cli/11.8.0 darwin-x64 node-v14.20.0 Maybe a Mac OS issue, it works fine on windows

cetchells avatar Sep 21 '22 10:09 cetchells

Also encountering the same issue with the latest version of Netlify CLI:

netlify-cli/11.8.2 darwin-x64 node-v16.8.0

analiamokbb avatar Sep 22 '22 18:09 analiamokbb

It seems like its actually Content-Length that is undefined, the body is actually there in the request but you check content-length header. If I remove the check for content length it works. https://github.com/netlify/cli/blob/fc2030468cab8a402c544a702e03e8629d542313/src/lib/functions/server.js#L71 I'm using axios to send the request

cetchells avatar Sep 23 '22 09:09 cetchells

@analiamokbb Could you provide a repository with the reproduction of the issue? I was trying to reproduce this issue but wasn't able to with the http client (HTTPie) that I'm using.


@cetchells Could you provide me the exact axios request you're using? Were you using Next.js or some other framework?

tinfoil-knight avatar Sep 23 '22 14:09 tinfoil-knight

@mclimb I made a simple reproduction similar to how you've described things in why-arent-my-netlify-functions-finding-a-body here: https://github.com/KK-Learning-Gym/5030-no-body (haven't used Next.js though)

I'm able to get the request body.

Could you provide me read access to the repository to help me debug your issue better? Seems like it's specific to the framework.

tinfoil-knight avatar Sep 24 '22 13:09 tinfoil-knight

Sorry for the late response. It may take awhile before I can setup an example repository, but the more exact environment conditions:

  • Next.js 12.3.1
    • No middleware implementations
  • Netlify CLI 12.0.8
  • @netlify/plugin-nextjs 4.25.0
  • axios 0.27.2
    • All axios requests to a netlify function manually configure 2 headers: Authorization: Bearer $token and Content-Type: application/json
  • Netlify function source files are under a custom directory and built with webpack 5
    • configuration is the same as what's generated in netlify-lambda
    • Issue was also occurring when using netlify-lambda cli
  • Typescript 4.5.2

I was able to verify that downgrading only the cli to 10.18.0 does not produce the issue. 11.0.0+ onward does cause an undefined response body.

Upgrading axios to 1.x does not resolve the issue.

analiamokbb avatar Oct 12 '22 19:10 analiamokbb

The following repo contains a reproduction of the issue: https://github.com/analiamokbb/next-netlify-example

Axios request can be seen in the Test component. Note: We do see the issue occurring for both GET and POST requests.

analiamokbb avatar Oct 13 '22 18:10 analiamokbb

This seems to be fixed in v12.0.9. At least the problem disappeared when I upgraded from v12.0.5.

Kyrremann avatar Oct 16 '22 11:10 Kyrremann

I upgraded to v12.0.9 and it did not fix the problem for me, it definitely is a bug. I created a workaround that isn't "hacky": just use queryStringParameters instead of sending JSON. I verified it works on both local development and production environments.

Example:

const json = { username: "me" };  
const searchParams = '?' + new URLSearchParams(json).toString();  
const response = await fetch("http://myurl.com/" + searchParams);

Now in your function event.queryStringParameters will contain the json.

jasoncarrillo0 avatar Oct 19 '22 06:10 jasoncarrillo0

This issue has been bothering me for weeks. I got it to work by downgrading netlify-cli to version 10. npm i -g netlify-cli@10

hongchiong avatar Oct 20 '22 09:10 hongchiong

@analiamokbb Thank you a lot for trying to provide a re-production of the issue.


Note: Sending GET requests with body is allowed by HTTP but not supported by axios. AFAIK other libraries too don't support sending body with GET requests especially on the browser.

From axios docs

// `data` is the data to be sent as the request body  
// Only applicable for request methods 'PUT', 'POST', 'DELETE', and 'PATCH'

I changed the existing GET request (in Test.tsx) to a POST request & added a request body.

I'm able to get the request body in the function for POST requests. The content-length header is also there.

Here's my log:

Request from ::1: POST /.netlify/functions/test
{
  path: '/api/test',
  httpMethod: 'POST',
  queryStringParameters: {},
  multiValueQueryStringParameters: {},
  headers: {
    host: 'localhost:8888',
    'x-deno-pass': 'passthrough',
    'x-nf-request-id': '6c3ea856-9c52-4153-8b99-e0a8f6037259',
    'x-nf-geo': <redacted>,
    'x-forwarded-for': '::1',
    'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/106.0.0.0 Safari/537.36',
    'sec-fetch-site': 'same-origin',
    'sec-fetch-mode': 'cors',
    'sec-fetch-dest': 'empty',
    'sec-ch-ua-platform': '"macOS"',
    'sec-ch-ua-mobile': '?0',
    'sec-ch-ua': '"Chromium";v="106", "Google Chrome";v="106", "Not;A=Brand";v="99"',
    referer: 'http://localhost:8888/',
    origin: 'http://localhost:8888',
    dnt: '1',
    'content-type': 'application/json',
    'content-length': '13',
    connection: 'close',
    'accept-language': 'en-GB,en;q=0.9',
    'accept-encoding': 'gzip, deflate, br',
    accept: 'application/json, text/plain, */*',
    'client-ip': '::1'
  },
  multiValueHeaders: {
    host: [ 'localhost:8888' ],
    'x-deno-pass': [ 'passthrough' ],
    'x-nf-request-id': [ '6c3ea856-9c52-4153-8b99-e0a8f6037259' ],
    'x-nf-geo': <redacted>,
    'x-forwarded-for': [ '::1' ],
    'user-agent': [
      'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/106.0.0.0 Safari/537.36'
    ],
    'sec-fetch-site': [ 'same-origin' ],
    'sec-fetch-mode': [ 'cors' ],
    'sec-fetch-dest': [ 'empty' ],
    'sec-ch-ua-platform': [ '"macOS"' ],
    'sec-ch-ua-mobile': [ '?0' ],
    'sec-ch-ua': [
      '"Chromium";v="106", "Google Chrome";v="106", "Not;A=Brand";v="99"'
    ],
    referer: [ 'http://localhost:8888/' ],
    origin: [ 'http://localhost:8888' ],
    dnt: [ '1' ],
    'content-type': [ 'application/json' ],
    'content-length': [ '13' ],
    connection: [ 'close' ],
    'accept-language': [ 'en-GB,en;q=0.9' ],
    'accept-encoding': [ 'gzip, deflate, br' ],
    accept: [ 'application/json, text/plain, */*' ],
    'client-ip': [ '::1' ]
  },
  body: '{"foo":"bar"}',
  isBase64Encoded: false,
  rawUrl: 'http://localhost:8888/api/test',
  rawQuery: ''
}
Response with status 200 in 1 ms.

Could you try sending POST requests with body once more & see if the issue is still occurring?

P.S. netlify-cli/12.0.11 darwin-arm64 node-v16.17.1

tinfoil-knight avatar Oct 21 '22 14:10 tinfoil-knight

I upgraded to v12.0.9 and it did not fix the problem for me, it definitely is a bug.

@jasoncarrillo0 Was this only for GET requests or for POST requests too?

tinfoil-knight avatar Oct 21 '22 14:10 tinfoil-knight

@tinfoil-knight only used with GET, but netlify functions don't seem to care which REST method you use

jasoncarrillo0 avatar Oct 21 '22 14:10 jasoncarrillo0

@tinfoil-knight only used with GET, but netlify functions don't seem to care which REST method you use

@jasoncarrillo0 This might not be related to Netlify CLI. Most client-side libraries (on the browser) don't support sending a request body with GET requests.

Could you update the Netlify CLI package & try again with a POST request in your client-side code?

tinfoil-knight avatar Oct 21 '22 14:10 tinfoil-knight

I ran into the same issue netlify functions:serve has a body for POST requests as expected However when usingnetlify dev or netlify dev --live the event.body is undefined.

thedavidthomas avatar Nov 14 '22 06:11 thedavidthomas

@thedavidthomas Are the requests made by your website to the functions GET requests? If yes, could you change them to one of these HTTP request methods: PUT, POST, DELETE, and PATCH & see if you're still experiencing the issue?

tinfoil-knight avatar Nov 14 '22 06:11 tinfoil-knight

Hi @tinfoil-knight

netlify-cli/12.1.1 darwin-x64 node-v16.17.0

I'm using the POST method

my simple function takes the body and returns it in the response

const handler = async event => {
  return {
    statusCode: 200,
    body: JSON.stringify({
      message: event.body,
    }),
  };
};

module.exports = {handler};

with netlify dev Screen Shot 2022-11-14 at 3 02 53 pm

with netlify functions:serve Screen Shot 2022-11-14 at 3 03 22 pm

as you can see with netlify dev the response is empty, where i would expect it to be the same as functions:serve

thedavidthomas avatar Nov 14 '22 07:11 thedavidthomas

@thedavidthomas That's a bit strange. I wasn't able to replicate this on my end. I created a simple function to return the request body as you've suggested & I'm getting the expected response for both dev & functions:serve.

Could you share a repo with the reproduction of the issue?

tinfoil-knight avatar Nov 18 '22 18:11 tinfoil-knight

any luck on getting this fixed? having the same issue - Thanks

marquez138 avatar Nov 18 '22 21:11 marquez138

hi @tinfoil-knight

I've made a reduced-case public repo for testing purposes https://github.com/thedavidthomas/next-netlify-functions-test

It's a Next.js app created using create-next-app command and same hello-world function from my earlier comment.

hopefully with this public repo you are able to replicate this:

netlify dev Starts on port 8888 by default, a POST request to http://localhost:8888/.netlify/functions/hello-world returns the empty body (the issue)

netlify functions:serve Starts on port 9999 by default, the same POST request sent to this http://localhost:9999/.netlify/functions/hello-world returns body as expected (correct)

Is it possibly something to do with next and the @netlify/plugin-nextjs? as netlify dev

For me netlify dev uses: @netlify/build 28.2.0 Next.js Runtime - v4.28.6

& netlify -v returns netlify-cli/12.2.4 darwin-x64 node-v16.17.0

It's not a problem for me because I can continue to use netlify functions:serve for my local testing but hopefully this can help reproduce

thedavidthomas avatar Nov 21 '22 09:11 thedavidthomas

@danez Can you take a look here & see if you're able to reproduce this issue?

For me, both netlify dev & netlify functions:serve send the expected response body for HTTP POST requests.

tinfoil-knight avatar Nov 27 '22 09:11 tinfoil-knight

Like @thedavidthomas, I have the exact same behavior. I got the header but the body is undefined

l5t avatar Dec 03 '22 07:12 l5t

This is fixed in https://github.com/netlify/cli/releases/tag/v12.2.9 🌻

danez avatar Dec 06 '22 17:12 danez

hallelujah! t'was driving me nuts having to work locally with stubbed requests and responses.

parkerthegeniuschild avatar Dec 10 '22 01:12 parkerthegeniuschild