Deploy failed due to upload file

Hi there,

I am trying to implement functions for my site but I am facing difficulty uploading functions during deploys.

3:00:59 PM: failed during stage ‘deploying site’: Failed to execute deploy: [PUT /deploys/{deploy_id}/functions/{name}][422] uploadDeployFunction default &{Code:0 Message:}
3:00:59 PM: Failed to upload file: &{Name:graphql Sum:bad8a421a0e409b56eaadceab514a53b543d1fada7eda8da997c6fbc2fbcfda0 Runtime:js Size: Path: Buffer:0xc0002e40c0}
3:00:59 PM: Failing build: Failed to deploy site

My env vars are short and the functions folder is under the AWS limit. Any debugging advice would be greatly appreciated.

du -h -d0 functions*
24M functions
4.0K functions.zip

Logs: https://app.netlify.com/sites/conversations/deploys/5dfc46773eddf700072ca606

Thanks!

Hi @Monish, from the deploy logs, it looks like you have 2 functions with the same name.

10:58:31 PM: [ { path: '/tmp/zisi-653529108/graphql.zip', runtime: 'js' },
10:58:31 PM:   { path: '/tmp/zisi-653529108/graphql.zip', runtime: 'js' },
10:58:31 PM:   { path: '/tmp/zisi-653529108/hello.zip', runtime: 'js' } ]

Can you make sure each of your functions have a unique name and see if that helps?

I’m facing the same problem here.

I built a static website from scratch with no external libraries and now I’m trying to implement submission-created.js for some form handling.

When I push the file to GitHub Netlify tries to deploy it but fails whith this error:

failed during stage ‘deploying site’: Failed to execute deploy: [PUT /deploys/{deploy_id}/functions/{name}][422] uploadDeployFunction default &{Code:0 Message:}

The complete log is as shown below

6:43:50 PM: Found Netlify configuration file netlify.toml in site root
6:43:50 PM: Found Netlify configuration file(s). Overriding site configuration
6:43:50 PM: No build command found, continuing to publishing
6:43:50 PM: Starting to deploy site from ‘/’
6:43:50 PM: Creating deploy tree
6:43:51 PM: 1 new files to upload
6:43:51 PM: 1 new functions to upload
6:46:00 PM: Failed to upload file: submission-created
6:46:00 PM: Failing build: Failed to deploy site
6:46:00 PM: failed during stage ‘deploying site’: Failed to execute deploy: [PUT /deploys/{deploy_id}/functions/{name}][422] uploadDeployFunction default &{Code:0 Message:}

Any help would be appreciated. Thanks!

Edit:

Initially the JavaScript function file I was trying to upload was empty, after putting some stuff in it I managed to deploy the repository. So maybe it has something to do with the file being blank…

1 Like

sounds very likely! thanks for posting your fix!

I’m facing the same issue. Here is what I’m seeing:

6:09:04 PM: Function Dir: /opt/build/repo/functions
6:09:04 PM: TempDir: /tmp/zisi-5e682a7279446d57fa1fab46
6:09:04 PM: Prepping functions with zip-it-and-ship-it 0.3.1
6:09:10 PM: [ { path:
6:09:10 PM:      '/tmp/zisi-5e682a7279446d57fa1fab46/contact-form-submitted.zip',
6:09:10 PM:     runtime: 'js' } ]
6:09:10 PM: Prepping functions complete
...
6:09:14 PM: 1 new functions to upload
6:11:43 PM: failed during stage 'deploying site': Failed to execute deploy: [PUT /deploys/{deploy_id}/functions/{name}][422] uploadDeployFunction default  &{Code:0 Message:}
6:11:43 PM: Failed to upload file: contact-form-submitted
6:11:43 PM: Failing build: Failed to deploy site

My function is not a duplicate and it is not empty.

Any ideas why this may happen?

Thanks!

Hey there, welcome to the forum :slight_smile: Sometimes, I’ve seen .zip files in the wrong shape (we expected a directory but only got a single zipped file, etc.) keep a site from building, so the first thing I’ll ask you to try is putting your function file inside a directory and trying again. If that doesn’t work, could you please share a Netlify URL and a repo (if it’s public)?

Hi @jen. Thanks!

Sorry for the delay in getting back on here.

I’ve tried the following:

  1. Moved function to a directory following this tip. I used the following structure: functions/contact-form-submitted/contact-form-submitted.js.

    This introduced the following webpack error: WebpackOptionsValidationError: Invalid configuration object. Webpack has been initialised using a configuration object that does not match the API schema. - configuration.entry should be an non-empty object.

  2. Added an empty function (with the required handler) to the functions directory (empty.js).

    This satisfied the webpack error, but the build ignored the nested function (functions/contact-form-submitted/contact-form-submitted.js)

I also tried completely renaming the function and got the same failed to execute deploy error.

Here is the Netlify URL: bristauss.netlify.app

I’ve set up other sites just like this via Netlify, but this is the only one giving me issues. Can’t seem to figure it why.

I went ahead and took the nuclear option. I completely deleted the site from Netlify, recreated it, deployed, and as expected the error went away.

Somewhere along the line Netlify was rejecting the function deploy. I believe it started happening when I migrated builds to, then from, Gatsby cloud. You’re required to set up your functions differently when using Gatsby Cloud. For whatever reason this messed things up somewhere.

I know the nuclear approach isn’t helpful, but it worked :confused:

Edit: After some investigating, it doesn’t seem to be from the Gatsby Cloud migration, but rather from attempting to implement gatsby-parallel-runner.

1 Like

awesome. I’m glad it worked!

I’m having this issue again. Can’t figure out what it is. I’ve spent a significant amount of time on it :frowning:

Is there a way to get better logging as to why my function won’t upload? I get no information about why and it’s left me completely in the dark. I literally have no idea where to start and I’m eating up all my build minutes testing out changes in an attempt to fix the issue.

Here’s the URL: bristauss.com (nuking it didn’t work this time around)

Here are some snippets from the log (there’s no indication of an error anywhere except on the file upload) :

...
1:39:34 PM: > gatsby build
1:39:35 PM: netlify-lambda: Building functions
1:39:38 PM: Hash: cbcfb92c04d0d64d771d
1:39:38 PM: Version: webpack 4.42.1
1:39:38 PM: Time: 1697ms
1:39:38 PM: Built at: 05/03/2020 7:39:38 PM
1:39:38 PM:                  Asset      Size  Chunks             Chunk Names
1:39:38 PM: submit-contact-form.js  3.81 KiB       0  [emitted]  submit-contact-form
1:39:38 PM: Entrypoint submit-contact-form = submit-contact-form.js
1:39:38 PM: [0] ./submit-contact-form.js 5.18 KiB {0} [built]
1:39:38 PM: [1] external "querystring" 42 bytes {0} [built]
1:39:38 PM: [2] external "humanparser" 42 bytes {0} [built]
1:39:38 PM: [3] external "validator" 42 bytes {0} [built]
1:39:38 PM: [4] external "request-promise" 42 bytes {0} [built]
1:39:38 PM: [5] external "node-mailjet" 42 bytes {0} [built]
...
1:45:27 PM: Prepping functions with zip-it-and-ship-it 0.3.1
1:45:32 PM: [ { path: '/tmp/zisi-5eaf1da246f7f40007b5534b/submit-contact-form.zip',
1:45:32 PM:     runtime: 'js' } ]
1:45:32 PM: Prepping functions complete
...
1:45:37 PM: Build script success
1:45:37 PM: Starting to deploy site from 'public'
1:45:38 PM: Creating deploy tree asynchronously
1:45:38 PM: Creating deploy upload records
1:45:41 PM: 14 new files to upload
1:45:41 PM: 1 new functions to upload
1:48:45 PM: Failed to upload file: submit-contact-form
1:48:45 PM: Failing build: Failed to deploy site
1:48:45 PM: failed during stage 'deploying site': Failed to execute deploy: [PUT /deploys/{deploy_id}/functions/{name}][422] uploadDeployFunction default  &{Code:0 Message:}
1:48:45 PM: Finished processing build request in 10m33.55768602s

Hi @bristizzy, your latest deploys are succeeding. Nice! Looks like the parallel runner is working? Let me know if you run into the issue again. I’m not sure why your functions are failing to upload but I raised your build timelimit a bit to see if that helps. Looks like it’ll not be needed at this point, right?

Hi @Dennis, thanks for getting back to me.

Yes, my builds are succeeding, but that’s because when I run gatsby-parallel-runner directly it actually skips the function build step. I did this intentionally to allow me to keep developing the site and in the mean time just took the form down that relies on the function.

Thanks for upping the build timelimit. I’ve adjusted the commands to allow function builds again and tested. Still failing to upload. It’s strange to me because I’ve used virtually the same function file for a few other projects with no issues.

I can’t quite figure out what’s causing it. Probably something trivial I’m missing 🤷.

Update: In a branch deploy I deleted the function, created a new function file with a completely different name, and added an exact copy of a function from a different site (where it uploads just fine). Still fails to upload. I’m at a loss.

Is there really no way to log what the error is? If I had an idea it would make troubleshooting easier.

hey there, i am sorry this is so frustrating. Are you getting any error messages?

No worries. Hopefully we’ll figure it out. I’m not seeing any error messages. The log just says it can’t upload the function file:

12:22:07 PM: Build script success
12:22:07 PM: Starting to deploy site from 'public'
12:22:08 PM: Creating deploy tree asynchronously
12:22:08 PM: Creating deploy upload records
12:22:10 PM: 22 new files to upload
12:22:10 PM: 1 new functions to upload
12:24:15 PM: Failed to upload file: contact-form-submitted
12:24:15 PM: Failing build: Failed to deploy site
12:24:15 PM: failed during stage 'deploying site': Failed to execute deploy: [PUT /deploys/{deploy_id}/functions/{name}][422] uploadDeployFunction default  &{Code:0 Message:}
12:24:15 PM: Finished processing build request in 6m11.437310105s

So, it seems the issue is specific to that specific function. Have you tried manually zipping up your functions? I have an example here: https://github.com/depadiernos/function-deploy-test/blob/master/package.json#L17. If that doesn’t work, could you share your function? I’d like to see if there’s something there that might be causing the buildbot to choke.

@Dennis, I’ll give that a try. It’s strange to me because I have this identical function on about 3 other netlify projects and they deploy just fine. I’ll give this a go and update you soon.

Thanks!

1 Like

@dennis, it took some finagling, but I was able to manually zip the file following the example you sent over. I can see that Netlify is attempting to upload the function but I still get the same failure:

12:22:58 PM: Build script success
12:22:58 PM: Starting to deploy site from 'public'
12:22:59 PM: Creating deploy tree asynchronously
12:23:00 PM: Creating deploy upload records
12:23:06 PM: 3 new files to upload
12:23:06 PM: 1 new functions to upload
12:25:56 PM: Failed to upload file: contact-form-submitted
12:25:56 PM: Failing build: Failed to deploy site
12:25:56 PM: Failed during stage 'deploying site': Failed to execute deploy: [PUT /deploys/{deploy_id}/functions/{name}][422] uploadDeployFunction default  &{Code:0 Message:}
12:25:56 PM: Finished processing build request in 6m14.542724321s

I diff-checked the function with a different website where the same function uploads fine. The two files are identical.

Without any form of information on why this is failing to upload I’m left to complete guesses as to what’s causing the failure.

Is there any way to get more information on why the function won’t upload?

Here’s the function in its current form:

const queryString = require("query-string")
const human = require("humanparser")
const validator = require("validator")
const rp = require("request-promise")

const {
  MAILJET_API_KEY,
  MAILJET_SECRET_KEY,
  FROM_EMAIL,
  FROM_NAME,
  TO_EMAIL,
  TO_NAME,
} = process.env
const mailjet = require("node-mailjet").connect(
  MAILJET_API_KEY,
  MAILJET_SECRET_KEY
)

const validateFormName = (payload, errors) => {
  if (!validator.equals(payload["form-name"], "Contact")) {
    errors.push({ param: "form-name", msg: "Invalid Form" })
  }
}
const validateFirstName = (payload, errors) => {
  payload.firstName = validator.trim(payload.firstName)
  if (validator.isEmpty(payload.firstName)) {
    errors.push({ param: "firstName", msg: "First Name Required" })
  }
  if (!validator.isLength(payload.firstName, { min: 2 })) {
    errors.push({ param: "firstName", msg: "Too Short" })
  }
  if (!validator.isLength(payload.firstName, { max: 50 })) {
    errors.push({ param: "firstName", msg: "Too Long" })
  }
  payload.firstName = validator.escape(payload.firstName)
}
const validateLastName = (payload, errors) => {
  payload.lastName = validator.trim(payload.lastName)
  if (validator.isEmpty(payload.lastName)) {
    errors.push({ param: "lastName", msg: "First Name Required" })
  }
  if (!validator.isLength(payload.lastName, { min: 2 })) {
    errors.push({ param: "lastName", msg: "Too Short" })
  }
  if (!validator.isLength(payload.lastName, { max: 50 })) {
    errors.push({ param: "lastName", msg: "Too Long" })
  }
  payload.lastName = validator.escape(payload.lastName)
}
const validateEmail = (payload, errors) => {
  payload.email = validator.trim(payload.email)
  if (validator.isEmpty(payload.email)) {
    errors.push({ param: "email", msg: "Email Required" })
  }
  if (!validator.isEmail(payload.email)) {
    errors.push({ param: "email", msg: "Must be a valid Email Address" })
  }
  payload.email = validator.normalizeEmail(payload.email)
}
const validateSubject = (payload, errors) => {
  payload.subject = validator.trim(payload.subject)
  if (validator.isEmpty(payload.subject)) {
    errors.push({ param: "subject", msg: "Subject Required" })
  }
  if (!validator.isLength(payload.subject, { min: 2 })) {
    errors.push({ param: "subject", msg: "Too Short" })
  }
  if (!validator.isLength(payload.subject, { max: 50 })) {
    errors.push({ param: "subject", msg: "Too Long" })
  }
  payload.subject = validator.escape(payload.subject)
}
const validateMessage = (payload, errors) => {
  payload.message = validator.trim(payload.message)
  if (validator.isEmpty(payload.message)) {
    errors.push({ param: "message", msg: "Message Required" })
  }
  if (!validator.isLength(payload.message, { min: 2 })) {
    errors.push({ param: "message", msg: "Too Short" })
  }
  if (!validator.isLength(payload.message, { max: 2000 })) {
    errors.push({ param: "message", msg: "Too Long" })
  }
  payload.message = validator.escape(payload.message)
}
const validateBotField = (payload, errors) => {
  if (!validator.isEmpty(payload.botField)) {
    errors.push({ param: "botField", msg: "Spam!" })
  }
}
const validateRecaptcha = async (payload, errors) => {
  if (validator.isEmpty(payload.recaptchaToken)) {
    errors.push({
      param: "recaptchaToken",
      msg: "Recaptcha Error - Empty Token",
    })
  }
  try {
    const response = await rp(
      `https://www.google.com/recaptcha/api/siteverify?secret=${process.env.SITE_RECAPTCHA_SECRET}&response=${payload.recaptchaToken}`
    ).json()
    if (response.success === undefined || response.success !== true) {
      errors.push({ param: "recaptchaToken", msg: "Recaptcha Error" })
    }
  } catch (e) {
    return {
      statusCode: 422,
      body: JSON.stringify({ errors: e }),
    }
  }
}

exports.handler = async event => {
  const payload = queryString.parse(event.body)
  const errors = []

  validateFormName(payload, errors)
  validateFirstName(payload, errors)
  validateLastName(payload, errors)
  validateEmail(payload, errors)
  validateSubject(payload, errors)
  validateMessage(payload, errors)
  validateBotField(payload, errors)
  await validateRecaptcha(payload, errors)

  const mapped = errors.reduce((mapping, error) => {
    if (!mapping[error.param]) {
      mapping[error.param] = error.msg
    }
    return mapping
  }, {})

  if (Object.getOwnPropertyNames(mapped).length !== 0) {
    return {
      statusCode: 422,
      body: JSON.stringify({ errors: mapped }),
    }
  } else {
    try {
      await mailjet.post("send", { version: "v3.1" }).request({
        "Messages": [
          {
            "From": {
              "Email": FROM_EMAIL,
              "Name": FROM_NAME,
            },
            "To": [
              {
                "Email": TO_EMAIL,
                "Name": TO_NAME,
              },
            ],
            "ReplyTo": {
              "Email": payload.email,
              "Name": payload.firstName,
            },
            "Subject": `Inquiry: ${payload.firstName}`,
            "TextPart": payload.message,
            "HTMLPart": `
              <h2>${payload.subject}</h2>
              <h3>Details</h3>
              <ul>
                <li><strong>Name</strong>: ${payload.firstName}</li>
                <li><strong>Email</strong>: ${payload.email}</li>
              </ul>
              <h3>Message</h3>
              <p>${payload.message}</p>
            `,
          },
        ],
      })

      const fullName = `${payload.firstName} ${payload.lastName}`

      return {
        statusCode: 200,
        body: JSON.stringify(human.parseName(fullName)),
      }
    } catch (err) {
      console.log("error: ", err)
      return {
        statusCode: 400,
        body: JSON.stringify({ error: err }),
      }
    }
  }
}

Update: I tried all three approaches in the example (lambda/bundled-function, labda/zipped-function, and functions/zisi-function). I get the same failure on all three.

Hey @bristizzy,

I’ve done some digging in to similar reports and it may boil down to one of four things.

  1. It could be an issue with charactersets; make sure you’re using appropriate charactersets (UTF-8).

  2. Lambda may be unable to configure your environment variables because the environment variables you have provided contain reserved keys that are currently not supported for modification.

  3. You can’t have a dot within the file name; best bet is to keep it alphanumeric.

  4. Any env vars cannot be >4k encoded, which we also know about in advance and should just prevent and error message to the customer, instead of 500’ing.

I’ll continue to dig around but if any of these help, please do feed back!

Hi @Pieparker, thanks for the suggestions. I’ll look into these.

I’m still really confused though. As stated in previous comments I have virtually the same function deployed on several other websites using Netlify. In fact, I just successfully deployed a website this week using the exact same function with no issues. The function uploads as expected.

I’m either missing something or there’s a bug somewhere.

Is there really no way to get more information on why it fails to upload? Seems like there should be.

Thanks.

Hey @bristizzy,

If you could link me to a failing deploy which features this function, I can take a look!