Question

Serverless Function Error: Cannot find module '@sendgrid/mail'

**Invoking a Function in the console returns this error in the console:

Error: Cannot find module '@sendgrid/mail'

In the output:

The function did not initialize properly.

The function was deployed from my local machine using:

doctl serverless deploy . --remote-build

This is the package.json file:

{
    "name": "my-func-name",
    "version": "1.0.0",
    "description": "My func desc",
    "main": "index.js",
    "scripts": {
      "test": "echo \"Error: no test specified\" && exit 1"
    },
    "author": "Mor Sagmon",
    "license": "ISC",
    "dependencies": {
      "@sendgrid/mail": "^7.7.0",
      "cors": "^2.8.5",
      "dotenv": "^16.3.1",
      "express": "^4.18.2"
    }
  }

And this is the index.js file:

const sgMail = require('@sendgrid/mail');

// Assuming SENDGRID_API_KEY and SENDER_EMAIL are set as environment variables
sgMail.setApiKey(process.env.SENDGRID_API_KEY);

async function main(args) {
    const { to, templateId, dynamicData, unsubscribeGroupId, emergencyByPass } = args;

    // Default response
    let response = { "body": "Invalid request payload" };

    // Validate the request payload
    if (!to || !templateId || !dynamicData) {
        return response;
    }

    // Construct the email object
    const msg = {
        to: to,
        from: process.env.SENDER_EMAIL,
        template_id: templateId,
        dynamic_template_data: dynamicData,
        mail_settings: { bypass_list_management: { enable: emergencyByPass } },
        ...(unsubscribeGroupId ? { asm: { group_id: unsubscribeGroupId } } : {}),
    };

    try {
        // Send the email using SendGrid
        await sgMail.send(msg);
        response.body = { message: 'Email sent successfully' };
    } catch (error) {
        console.error(error);
        response = { "body": { "error": 'Failed to send email', details: error.message } };
    }

    return response;
}

And the project.yml file:

parameters: {}
environment: {}
packages:
    - name: app
      shared: false
      environment: {}
      parameters: {}
      annotations: {}
      functions:
        - name: security
          binary: false
          main: ""
          runtime: nodejs:18
          web: true
          webSecure: false
          parameters: {}
          environment: {}
          annotations: {}
          limits: {
            timeout: 3000
          }
        - name: send-email
          binary: false
          main: ""
          runtime: nodejs:18
          web: true
          webSecure: false
          parameters: {}
          environment: {}
          annotations: {}
          limits: {
            timeout: 8000
          }

What am I missing here?


Submit an answer


This textbox defaults to using Markdown to format your answer.

You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!

Sign In or Sign Up to Answer

These answers are provided by our Community. If you find them useful, show some love by clicking the heart. If you run into issues leave a comment, or add your own answer to help others.

Bobby Iliev
Site Moderator
Site Moderator badge
March 7, 2024
Accepted Answer

Hey hey!

I’ve just tried to reproduce this on my end:

  • My hello.js:
const sgMail = require('@sendgrid/mail');

async function main(args) {
    if (sgMail) {
        console.log('sgMail is available');
    } else {
        console.log('sgMail is not available');
    }
    return {"body": "Hello World!"};
}

exports.main = main;
  • My package.json:
{
    "name": "hello-world",
    "version": "1.0.0",
    "description": "My func desc",
    "main": "hello.js",
    "scripts": {
      "test": "echo \"Error: no test specified\" && exit 1"
    },
    "author": "Mor Sagmon",
    "license": "ISC",
    "dependencies": {
      "@sendgrid/mail": "^7.7.0",
      "cors": "^2.8.5",
      "dotenv": "^16.3.1",
      "express": "^4.18.2"
    }
}
  • My project.yaml:
parameters: {}
environment: {}
packages:
  - name: sample
    shared: false
    environment: {}
    parameters: {}
    annotations: {}
    functions:
      - name: hello
        binary: false
        main: ""
        runtime: nodejs:18
        web: true
        webSecure: false
        parameters: {}
        environment: {}
        annotations: {}
        limits:
          timeout: 90000
  • Running the function:

Maybe try adding exports.main = main; in your index.js? If this still does not work, could you share the structure of your repository? Or possibly feel free to setup a demo GitHub project and share the link here so I could test your code directly and submit a PR with posssible fixes!

Best,

Bobby

This is now solved. It seems to be a bug on DO’s end. I had a .ignore file with a single line in it: node_modules. However, there was no node_modules folder. Once I deleted the .ignore file - it worked with no complaining on missing dependencies.

It seems like some bug in the way DO interprets the .ignore file for the Function. After all, if I’m ignoring a missing file/folder - it should not break dependencies…

Try DigitalOcean for free

Click below to sign up and get $200 of credit to try our products over 60 days!

Sign up

Get our biweekly newsletter

Sign up for Infrastructure as a Newsletter.

Hollie's Hub for Good

Working on improving health and education, reducing inequality, and spurring economic growth? We'd like to help.

Become a contributor

Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation.

Welcome to the developer cloud

DigitalOcean makes it simple to launch in the cloud and scale up as you grow — whether you're running one virtual machine or ten thousand.

Learn more
DigitalOcean Cloud Control Panel