Issues with deploying serverless functions using Netlify API

I’m trying to use the Netlify API to deploy functions and I’m following this “Deploy via API” docs.

With File Digest method:

  1. Create a site and get the site id from response:
curl --request POST 'https://api.netlify.com/api/v1/sites' \
--header 'Authorization: Bearer $NETLIFY_TOKEN'
  1. Create a new deployment for that site with function metadata and the deploy_id from response:
curl --request POST 'https://api.netlify.com/api/v1/sites/d297fc64-1692-4146-b184-66975d507448/deploys' \
--header 'Authorization: Bearer $NETLIFY_TOKEN' \
--header 'Content-Type: application/json' \
--data-raw '{
  "functions": {"hello-world": "deb21d35d1a9a876b01d67152bbf3f666a728653"}
}'

And it returned 200 response with required_functions parameter as above.

  1. Upload the serviceless function using functions API:
curl --request PUT 'https://api.netlify.com/api/v1/deploys/60ff7b22a54bc2535f6754da/functions/hello-world?runtime=js' \
--header 'Content-Type: application/octet-stream' \
--header 'Authorization: Bearer $NETLIFY_TOKEN' \
--data-binary '@/Users/sri/test-netlify-fns/hello-world.js'

And it returns the following 400 response:

{ "errors": "Deploy has already been finalized." }

I tried using zip file instead of direct js file in the body, but it still returns the above error.

  1. I also tried uploading the function using files API:
curl --request PUT 'https://api.netlify.com/api/v1/deploys/60ff7b22a54bc2535f6754da/files/hello_world.js' \
--header 'Content-Type: application/octet-stream' \
--header 'Authorization: Bearer $NETLIFY_TOKEN' \
--data-binary '@/Users/sri/test-netlify-fns/hello-world.js'

And it returns the following 401 response (which is not a proper json):

{
    "code": 401,
    "message": "Access Denied: deploy must be in , not new"
}
{
    "code": 401,
    "message": "Access Denied: User does not have access"
}

I did try above request with same headers/data on different site (which has some static files) and it returns 200 response. So, it’s not a credential issue.

Can someone help me to figure what’s the issue here?

Hi @ramsrib,

I see you’re uploading .js as a function. Functions must be zipped before upload. Could you try that?

yeah, I tried that (i.e just zipping the js file directly without any other directory/content), but still getting the same error.

Hi @ramsrib,

That’s not how functions are probably zipped. You could try creating a blank function file and running netlify build locally (considering you’ve netlify-cli installed. You can then see, the zipping of functions is handled slightly differently.

As you suggested, i ran netlify build which generated a zip file inside .netlify/functions directory. And then used that zipped file to upload

curl --request PUT 'https://api.netlify.com/api/v1/deploys/60ff5cf53fea4929a4cab6b9/functions/hello-world?runtime=js' \
--header 'Content-Type: application/zip' \
--header 'Authorization: Bearer $NETLIFY_TOKEN' \
--data-binary '@/Users/sri/test-netlify-fns/.netlify/functions/hello-world.zip'

And got 400 response:

{
    "errors": "Deploy has already been finalized."
}

Also the zip file that build generated looks like similar to mine:

➜  test-netlify-fns unzip -l .netlify/functions/hello-world.zip
Archive:  .netlify/functions/hello-world.zip
  Length      Date    Time    Name
---------  ---------- -----   ----
      535  01-01-1980 00:00   hello-world.js
---------                     -------
      535                     1 file

Hi @ramsrib,

Sorry to take longer to get back to you. After an internal discussion, this appears to be a bug. For the time being, you’d have to upload a file with the function. Uploading only the function would result in this error. Do make sure to upload the function before uploading the file.

I’ve filed an internal issue and would update this thread whenever it’s fixed.

1 Like

Hi @ramsrib,

This is now fixed. Let us know if you’re still having issues.

@hrishikesh
what do you mean to upload the function before uploading the file?
I do the following:

  1. Send deployment with payload similar to
    {
    “functions”: {“publisher”: “deb21d35d1a9a876b01d67152bbf3f666a728653”}
    }
  2. get a response with required_functions parameter
  3. upload publisher.js content

I see the function in the dashboard but can’t make a call.
Unfortunately, I can’t upload the screenshot here. This editor fails with an error on upload.
Maybe the link to my site will help you to investigate the issue
https://app.netlify.com/sites/delicate-longma-7da988

Maybe should I zip publisher.js to publisher.zip before deployment and start from step 1?

Functions always need to be zipped.

Note that, simply zipping a function is not the solution. You need to bundle all the dependencies and zip it. It’s recommended to use Netlify CLI to produce a valid zip.