"send-email" template doesn't work

So I’ve been having this issue for some weeks, and I’m not finding any solution to it yet.

Here is what’s going on:

  • I create this Netlify serverless function template (the “send-email” one, via the Netlify CLI. Uses the package “sendmail”).
  • I test it in local first, and works like a charm (even with some tweaks to customise it a bit).
  • I deploy it with the confidence that it will run with no problem like in local. WRONG! I get a timeout error!
  • [Extra] I do get all the information through the function’s logs, and everything seems alright (I don’t get any errors until the timeout), but it doesn’t finish sending the emails.

At least with a standard account in Netlify, the maximum time a serverless function can take is up to 10 seconds, although when tested in local it takes less than 5.

I have tried a lot of things, solutions to (kinda) similar problems people had and commented about in different forums, etc… But none of them made any positive difference to my case!

Has anybody had any similar experience? Does anybody know how to solve this?
Thank you beforehand!

1 Like

Please share a site name and reproduction steps to check.

Hello, I shared it in the post.
In Netlify’s CLI tool I add this “send-email” function and it works in local, but not when deployed.

OK, we’ll still want to see the deployment so we can try to advise you about it. If you don’t want to tell us, that’s fine, but we can’t provide any advice in that case.

I see! Here’s the deploy log:

11:24:56 PM: Build ready to start
11:25:00 PM: build-image version: cd0a67ec27b8bcd87e2a257fe5ebcf1900a8021d (focal)
11:25:00 PM: buildbot version: f3871d4c438bbd4f48a8f44a50bec7489430735e
11:25:00 PM: Fetching cached dependencies
11:25:01 PM: Starting to download cache of 141.8MB
11:25:02 PM: Finished downloading cache in 1.402s
11:25:02 PM: Starting to extract cache
11:25:03 PM: Finished extracting cache in 1.414s
11:25:03 PM: Finished fetching cache in 2.88s
11:25:03 PM: Starting to prepare the repo for build
11:25:04 PM: Preparing Git Reference refs/heads/main
11:25:05 PM: Parsing package.json dependencies
11:25:07 PM: Starting to install dependencies
11:25:07 PM: Python version set to 3.8
11:25:07 PM: Attempting Ruby version 2.7.2, read from environment
11:25:08 PM: Using Ruby version 2.7.2
11:25:08 PM: Started restoring cached go cache
11:25:08 PM: Finished restoring cached go cache
11:25:08 PM: Installing Go version 1.19.5 (requested 1.19.5)
11:25:14 PM: go version go1.19.5 linux/amd64
11:25:14 PM: Using PHP version 8.0
11:25:15 PM: Started restoring cached Node.js version
11:25:16 PM: Finished restoring cached Node.js version
11:25:16 PM: v20.0.0 is already installed.
11:25:17 PM: Now using node v20.0.0 (npm v9.6.4)
11:25:17 PM: Enabling Node.js Corepack
11:25:17 PM: Started restoring cached build plugins
11:25:17 PM: Finished restoring cached build plugins
11:25:17 PM: Started restoring cached corepack dependencies
11:25:17 PM: Finished restoring cached corepack dependencies
11:25:18 PM: Found pnpm version (8.3.1) that doesn’t match expected ()
Usage Error: Invalid package manager specification in CLI arguments; expected a semver version, range, or tag
11:25:18 PM: $ corepack prepare [–activate] [–all] [–json] [-o,–output] …
11:25:18 PM: No pnpm workspaces detected
11:25:18 PM: Started restoring cached node modules
11:25:18 PM: Finished restoring cached node modules
11:25:18 PM: Installing npm packages using pnpm version 8.3.1
11:25:18 PM: Lockfile is up to date, resolution step is skipped
11:25:19 PM: Already up to date
11:25:19 PM: Done in 764ms
11:25:19 PM: npm packages installed using pnpm
11:25:19 PM: Install dependencies script success
11:25:19 PM: Starting build script
11:25:20 PM: Detected 1 framework(s)
11:25:20 PM: “astro” at version “2.3.2”
11:25:20 PM: Section completed: initializing
11:25:22 PM: ​
11:25:22 PM: Netlify Build
11:25:22 PM: ────────────────────────────────────────────────────────────────
11:25:22 PM: ​
11:25:22 PM: ❯ Version
11:25:22 PM: @netlify/build 29.10.1
11:25:22 PM: ​
11:25:22 PM: ❯ Flags
11:25:22 PM: baseRelDir: true
11:25:22 PM: buildId: 64581728d1b187000769538b
11:25:22 PM: deployId: 64581728d1b187000769538d
11:25:22 PM: ​
11:25:22 PM: ❯ Current directory
11:25:22 PM: /opt/build/repo
11:25:22 PM: ​
11:25:22 PM: ❯ Config file
11:25:22 PM: /opt/build/repo/netlify.toml
11:25:22 PM: ​
11:25:22 PM: ❯ Context
11:25:22 PM: production
11:25:23 PM: ​
11:25:23 PM: 1. @netlify/plugin-functions-install-core (onPreBuild event)
11:25:23 PM: ────────────────────────────────────────────────────────────────
11:25:23 PM: ​
11:25:23 PM: Installing functions dependencies
11:25:24 PM: ​
11:25:24 PM: (@netlify/plugin-functions-install-core onPreBuild completed in 751ms)
11:25:24 PM: ​
11:25:24 PM: 2. build.command from netlify.toml
11:25:24 PM: ────────────────────────────────────────────────────────────────
11:25:24 PM: ​
11:25:24 PM: $ pnpm build
11:25:24 PM: > stevenreina@0.0.1 build /opt/build/repo
11:25:24 PM: > astro build
11:25:26 PM: 09:25:26 PM [content] No content directory found. Skipping type generation.
11:25:26 PM: 09:25:26 PM [build] output target: server
11:25:26 PM: 09:25:26 PM [build] deploy adapter: @astrojs/netlify/functions
11:25:26 PM: 09:25:26 PM [build] Collecting build info…
11:25:26 PM: 09:25:26 PM [build] Completed in 63ms.
11:25:26 PM: 09:25:26 PM [build] Building server entrypoints…
11:25:27 PM: 09:25:27 PM [build] Completed in 1.32s.
11:25:27 PM:
11:25:27 PM: building client
11:25:27 PM: Completed in 537ms.
11:25:27 PM:
11:25:27 PM:
11:25:27 PM: finalizing server assets
11:25:27 PM: 09:25:27 PM [build] Rearranging server assets…
11:25:27 PM: 09:25:27 PM [build] Server built in 1.94s
11:25:27 PM: 09:25:27 PM [build] Complete!
11:25:27 PM: ​
11:25:27 PM: (build.command completed in 3.3s)
11:25:27 PM: ​
11:25:27 PM: 3. Functions bundling
11:25:27 PM: ────────────────────────────────────────────────────────────────
11:25:27 PM: ​
11:25:27 PM: Packaging Functions from .netlify/functions-internal directory:
11:25:27 PM: - entry.mjs
11:25:27 PM: ​
11:25:27 PM: Packaging Functions from netlify/functions directory:
11:25:27 PM: - send-email/send-email.js
11:25:27 PM: ​
11:25:28 PM: ​
11:25:28 PM: ❯ The following Node.js modules use dynamic expressions to include files:
11:25:28 PM: - astro
11:25:28 PM: ​
11:25:28 PM: Because files included with dynamic expressions aren’t bundled with your serverless functions by default,
this may result in an error when invoking a function. To resolve this error, you can mark these Node.js
11:25:28 PM: modules as external in the [functions] section of your netlify.toml configuration file:
11:25:28 PM: ​
11:25:28 PM: [functions]
11:25:28 PM: external_node_modules = [“astro”]
11:25:28 PM: ​
11:25:28 PM: Visit File-based configuration | Netlify Docs for more information.
11:25:28 PM: ​
11:25:28 PM: ​
11:25:28 PM: (Functions bundling completed in 481ms)
11:25:28 PM: ​
11:25:28 PM: 4. Deploy site
11:25:28 PM: ────────────────────────────────────────────────────────────────
11:25:28 PM: ​
11:25:28 PM: Starting to deploy site from ‘dist’
11:25:28 PM: Calculating files to upload
11:25:28 PM: 0 new files to upload
11:25:28 PM: 1 new functions to upload
11:25:35 PM: Section completed: deploying
11:25:35 PM: Site deploy was successfully initiated
11:25:35 PM: ​
11:25:35 PM: (Deploy site completed in 6.6s)
11:25:35 PM: Starting post processing
11:25:35 PM: ​
11:25:35 PM: Netlify Build Complete
11:25:35 PM: ────────────────────────────────────────────────────────────────
11:25:35 PM: ​
11:25:35 PM: Skipping HTML post processing
11:25:35 PM: (Netlify Build completed in 12.7s)
11:25:35 PM: Post processing - header rules
11:25:35 PM: Post processing - redirect rules
11:25:35 PM: Caching artifacts
11:25:35 PM: Started saving node modules
11:25:35 PM: Finished saving node modules
11:25:35 PM: Started saving build plugins
11:25:35 PM: Post processing done
11:25:35 PM: Finished saving build plugins
11:25:35 PM: Started saving corepack cache
11:25:35 PM: Finished saving corepack cache
11:25:35 PM: Section completed: postprocessing
11:25:35 PM: Started saving pip cache
11:25:35 PM: Finished saving pip cache
11:25:35 PM: Started saving emacs cask dependencies
11:25:35 PM: Finished saving emacs cask dependencies
11:25:35 PM: Started saving maven dependencies
11:25:35 PM: Finished saving maven dependencies
11:25:35 PM: Started saving boot dependencies
11:25:35 PM: Finished saving boot dependencies
11:25:35 PM: Started saving rust rustup cache
11:25:35 PM: Finished saving rust rustup cache
11:25:35 PM: Started saving go dependencies
11:25:35 PM: Finished saving go dependencies
11:25:36 PM: Site is live :sparkles:
11:25:35 PM: Build script success
11:25:35 PM: Section completed: building
11:25:36 PM: Uploading Cache of size 136.4MB
11:25:37 PM: Section completed: cleanup
11:25:37 PM: Finished processing build request in 37.094s

Note that it warns about having some specific configuration for astro projects. I tried changing what it says, but then the deploy fails, which confuses me even more. I think I read about that a while ago, about it being some kind of wrong warning or something.

How do we reproduce the timeout errors? I tried making a POST request to: stevenreina.com/.netlify/functions/send-email, but it keeps failing with body.name must be a string. Please share a reproduction of the issue.

  1. How to reproduce the timeout errors? Running the function. I don’t know what else to say. It works in local, but not when deployed.
  2. “body.name” is part of the function.

If I asked you that, I think it means I don’t know how to run the function, the way it’s supposed to be run. It clearly needs some specific data to parse, which you know, I don’t.

I can guess that part. But I tried:

{ 
  "name": "foo"
}

and

{
  "body": {
    "name: "foo"
  }
}

and both failed with the same error. So, I need you to tell me what the expected data structure is.

It would be much useful if you can share a reproduction as a sample repository as requested.

It works with query parameters (so “?name=foo&…”) in the REQUEST BODY, rather than the URL.
It expects at least 3 parameters: name, email, and message.

Finally reproduced with:

curl --data-urlencode "email=foo@bar.com" --data-urlencode "message=foo-foo-foo" --data-urlencode "name=foo" -H "Content-Type: application/x-www-form-urlencoded" "https://stevenreina.com/.netlify/functions/send-email"

Could you add some logging in your functions: [Support Guide] Why is my function taking long or timing out? or share the code?

Alright, so this is what I’ve found out:
The function works, but it’s just that one package (“sendmail”) that is causing trouble. I’ve been testing with console.time on the different parts of the serverless function, but ONLY in the part where I send the data with the function from the “sendmail” package, sometimes it takes 7 seconds to run, sometimes 15 seconds or more, but I’ll have to suppose that it never took less than 10 seconds when deployed anyway, so it always throws that timeout error.
I don’t understand what I’m supposed to do with this, since it’s Netlify itself that proposes that way of sending an email, but ironically it never works, and I haven’t found any alternative package to do this (faster, perhaps too?)…

Emailjs has worked great for me in the past: emailjs - npm (npmjs.com)

I forgot to say it, but I don’t have access to any SMTP server. This package lets me build this contact page, and I want to repeat it: it’s Netlify’s own alternative

Maybe SendGrid is limiting something from its end? This was a situation I found last time: SendGrid not sending from Netlify Functions - #4 by m_glass

That’s using another package, for which I have to make an account. I’d rather find a less “expanded” alternative, if possible.

Did you even check the package? It’s just a SMTP client and works with any SMTP provider. It doesn’t need any other account.

You didn’t mention any package, just said that it could be an issue with SendGrid, for which I haven’t any account. And besides that, I repeat: I don’t have any SMTP server to use.
I just want to know how to do what the function is intended to do, basically without using any other resources.

Sorry, I assumed you’re using SendGrid. But if you don’t have a SMTP server to you, how are you sending emails?

Even if you’re using our integration: Netlify Email Integration | Netlify Docs, you’d need to select one of the providers. Each of these is a SMTP provider. If you created an account with them, you should be having a SMTP account setup. Then you can just use a library like: emailjs - npm (npmjs.com) to send emails.

Again, we can speed up this entire discussion, if you simply provide us a minimal reproduction example in the form of a repo, so we can check and know your actual configuration and possibly provide a solution/workaround.

Please, I suggest you to read, at least, the initial post thoroughly, in order to understand the issue I’m having, what I’ve used, how I did it, and what I’m trying to achieve. And I don’t consider necessary to send you the source code, as I think it could be an avoidable security and/or privacy risk on my end.
Besides, again, the function template (provided by Netlify ITSELF) uses the package “sendmail”, which EXPRESSLY allows emails to be sent, without setting up an SMTP server.


If it helps to debug this, this is the netlify.toml file in my project:

[build]
command = "pnpm build"

[[plugins]]
package = "@netlify/plugin-functions-install-core"

[functions]
external_node_modules = ["sendmail"]

And note that besides the build section, the rest of the configuration has been part of the “half solution” (without those, the project refuses to build correctly).

Without a reproduction, I’m sorry, I’m not going to spend any more time on this thread. I tried using sendmail package: sendmail - npm (npmjs.com) and it provides little to no documentation. I tried writing the code like this:

import sendmail from 'sendmail'
export async function handler() {
  const sendmailInstance = sendmail({})
  return new Promise((resolve, reject) => {
    sendmailInstance({
      from: 'test@test.com',
      html: 'test',
      subject: 'test',
      to: 'my personal gmail address'
    }, (err, reply) => {
      if (err) {
        reject(err)
      }
      if (reply) {
        resolve(reply)
      }
    })
  }).then(() => {
    return {
      body: JSON.stringify({
        status: 'success'
      }),
      headers: {
        'content-type': 'application/json'
      },
      statusCode: 200
    }
  }, () => {
    return {
      body: JSON.stringify({
        status: 'error'
      }),
      headers: {
        'content-type': 'application/json'
      },
      statusCode: 500
    }
  })
}

but ran into the error explained here: can’t send mail to gmail · Issue #37 · guileen/node-sendmail (github.com)

I don’t have an email at custom domain to test this (Netlify uses Gmail as well). The library provides no information on what the basic expected values should be, or what the configuration options do. It’s anyways been about 4 years since the library was last updated.

The template “provided by Netlify” as you mention, is not written or maintained by Netlify and it’s been last updated about 5 years ago: graphql-modules/website/lambda/contact.js at 8cb2fd7d9938a856f83e4eee2081384533771904 · Urigo/graphql-modules (github.com). I won’t be surprised if it’s not working in today’s date.

Your options?

  1. Provide me with a repo or a minimal example that you think should work, but doesn’t, or it works locally but not in production. I’d also need the values needed to be used.
  2. Simply use a SMTP provider (there are various SMTP providers available for free) and move on from this problematic package that doesn’t seem to be maintained anymore.

If both of these options are unacceptable, I’m sorry but there’s nothing more to debug here from our end.