Sendgrid-nodejs: Unexpected Error when trying to send transactional email

Created on 31 Aug 2017  ·  23Comments  ·  Source: sendgrid/sendgrid-nodejs

Issue Summary

Getting a 'Bad Request' error with the following payload.

Request

cosnt msg = {
        "to": "[email protected]",
        "from": "[email protected]",
        "subject": "Support Pay Transparency at PayCheck",
        "templateId": "24ae3147-4faa-4380-8613-c5be144f4542",
        "customArgs": {
            "ally_id": "cj6zlh7yd000001qir4r5suuk"
        }
};
sgMail.send(msg)

Response

{
        "message": "Bad Request",
        "code": 400,
        "response": {
            "headers": {
                "server": "nginx",
                "date": "Wed, 30 Aug 2017 22:30:41 GMT",
                "content-type": "application/json",
                "content-length": "365",
                "connection": "close",
                "access-control-allow-origin": "https://sendgrid.api-docs.io",
                "access-control-allow-methods": "POST",
                "access-control-allow-headers": "Authorization, Content-Type, On-behalf-of, x-sg-elas-acl",
                "access-control-max-age": "600",
                "x-no-cors-reason": "https://sendgrid.com/docs/Classroom/Basics/API/cors.html"
            },
            "body": {
                "errors": [
                    {
                        "message": "Unless a valid template_id is provided, the content parameter is required. There must be at least one defined content block. We typically suggest both text/plain and text/html blocks are included, but only one block is required.",
                        "field": "content",
                        "help": "http://sendgrid.com/docs/API_Reference/Web_API_v3/Mail/errors.html#message.content"
                    }
                ]
            }
        }
    }

Notes

In the documentation it says templateId but in the error message it says template_id. I've tried both and received the same error message. I attached a screenshot of my template screen as a sanity check to make sure I have it configured correctly in sendgrid.

Technical details:

  • sendgrid-nodejs Version: master (latest commit: [commit number])
  • Node.js Version: 6.10.3
  • Running in an AWS Lambda function

screen shot 2017-08-30 at 6 43 57 pm

help wanted bug

Most helpful comment

Thanks for the help peeps. I was literally losing my mind. I finally figured out a workaround late last night and was coming here to report more information, but it seems like you all are already on it :-)

All 23 comments

@onesien the new node JS mailer API is case agnostic, so you can use both templateId or template_id. Camel case is more common in JS land, hence we've added support for that, while the API itself consumes snake case.

I'll have a look to see what's happening with the template ID

Hi @onesien,

You might also want to check with support. I think the issue may be related to the old template editor.

Can you also try making a new template and using that ID?

With Best Regards,

Elmer

@thinkingserious can you check this on your end? It does seem like we are correctly sending the template_id parameter with the request. I've just created a new template and am getting this issue as well.

@adamreisnz,

My local tests are working, but I only have new templates on our account.

I will double check

Nope, I used a new template, freshly created, getting the same issue

The following works for me (using version v6.1.1) following the example here:

// Setup sendgrid api
const sendGridMail = require('@sendGrid/mail');
sendGridMail.setApiKey(process.env.SENDGRID_API_KEY);
sendGridMail.setSubstitutionWrappers('-', '-');

//build object 
var mailOptions = {
    personalizations:[{
      to: '[email protected]',
      substitutions: {'name':'John', 'city':'Denver'}
    }],
    from: '[email protected]',
    reply_to: '[email protected]',
    subject: 'Hello',
    html: 'email text goes here',
    templateId: '13b8f94f-bcae-4ec6-b752-70d6cb59f932'
  };

//send 
sendGridMail.send(mailOptions);

Ah, I think we have an old bug resurfacing, where the API is requiring a content block in all cases. So this works:

// Setup sendgrid api
const sendGridMail = require('@sendGrid/mail');
sendGridMail.setApiKey(process.env.SENDGRID_API_KEY);
sendGridMail.setSubstitutionWrappers('-', '-');

//build object 
var mailOptions = {
    to: '[email protected]',
    from: '[email protected]',
    reply_to: '[email protected]',
    subject: 'Hello',
    templateId: '13b8f94f-bcae-4ec6-b752-70d6cb59f932',
    html: ' ',
    substitutions: {
      name: 'Some One',
      city: 'Denver',
    }
  };

//send 
sendGridMail.send(mailOptions);

but not this:

// Setup sendgrid api
const sendGridMail = require('@sendGrid/mail');
sendGridMail.setApiKey(process.env.SENDGRID_API_KEY);
sendGridMail.setSubstitutionWrappers('-', '-');

//build object 
var mailOptions = {
    to: '[email protected]',
    from: '[email protected]',
    reply_to: '[email protected]',
    subject: 'Hello',
    templateId: '13b8f94f-bcae-4ec6-b752-70d6cb59f932',
    substitutions: {
      name: 'Some One',
      city: 'Denver',
    }
  };

//send 
sendGridMail.send(mailOptions);

Checking internally...

I had to add the content block to get the template to be sent. I was getting a _Bad Request (400) "Unless a valid template_id is provided, the content parameter is required. There must be at least one defined content block..."_ while using template created in the new html editor.

sgMail.setApiKey(sgKey);
sgMail.setSubstitutionWrappers('-', '-');
var msg: any = {
  to: email,
  from: '[email protected]',
  templateId: 'xxxxxxx',
  substitutions: {
     verifyUrl: createAccountLink
  }
};
sgMail.send(msg)

If I add the content block, the template email is sent as formatted in the html editor.

sgMail.setApiKey(sgKey);
sgMail.setSubstitutionWrappers('-', '-');
var msg: any = {
  to: email,
  from: '[email protected]',
  content: [{"type":"text/html","value":"0"}],
  templateId: 'xxxxxx',
  substitutions: {
     verifyUrl: createAccountLink
  }
};
sgMail.send(msg)

OK, I'm leaving this open as a bug.

My guess is that this SDK is adding an empty content object when it's not set. I think we need to skip these functions when html and txt is not set.

For now, the above workaround will do what you need.

@thinkingserious I think you're right. I read the API docs and thought the field was mandatory. It only has a well hidden comment (which is amazingly styled!) that I missed:

image

I will create a PR to address this!

Hehe, thanks Adam!

PR is up, this should fix the issue and not send the content field with the request if there is no content provided.

Thanks for the help peeps. I was literally losing my mind. I finally figured out a workaround late last night and was coming here to report more information, but it seems like you all are already on it :-)

Sorry about that @onesien,

The fix has just been pushed to npm (v6.1.2).

I used the code verbatim from the response of @thinkingserious and am still running into issues.

I'm just trying to get the most basic substitutions in a template i created in sengrid to get sent. The response in CloudWatch (since this is running in Lambda) is showing as 202 but the email i receive is: A message was received from this address by our systems that had errors in the smtpapi header, and cannot be processed. The error detected was: The template id must be a valid template id for your account.

What am I doing wrong here guys? I'm trying to sift thru the sendgrid docs but everything feels really piecemeal.

How are you sending the template ID? Is it through an environmental variable when the lambda is called?

thanks for the fast reply @cbilliau -- no in my case the template string is hardcoded since i'm just trying to get the functional scaffolding up between front and back end. My example verbatim is:

const sgMail = require("@sendgrid/mail");
sgMail.setApiKey(
  "XXXXX"
);
sgMail.setSubstitutionWrappers("%", "%"); // Configure the substitution tag wrappers globally
  const msg = {
    to: formFields.toEmail,
    from: formFields.fromEmail,
    subject: "Hello world",
    text: "test",
    html: "<p>test</p>",
    templateId: "be2cc0da-5b2c-428f-8e45-c140f6cfb6eb",
    substitutions: {
      name1: formFields.fromName,
      name2: formFields.fromName,
      date: formFields.date
    }
  };

  sgMail.send(msg);

@tetreault Checkout my answer above, I add content: [{"type":"text/html","value":"0"}], to my function and it worked. Unknown why.

just tried it, unfortunately didn't change the end result @cbilliau :(. Got the same email back:

A message was received from this address by our systems that had errors in the smtpapi header, and cannot be processed. 
The error detected was: The template id must be a valid template id for your account. You provided be2cc0da-5b2c-428f-8e45-c140f6cfb6eb 

wow let me bow out for a sec @cbilliau 🤣 i just was rushing thru stuff and didn't pay more attention. I realized i was grabbing the unique ID for a template i made under "marketing" but not under "transactional templates". I don't use the sendgrid UI much and just totally botched this one lol

Total face palm, fixing on my end and then hopefully expecting it to work.

kk - confirming its working now, especially using the content: [{ type: "text/html", value: "0" }] line that @cbilliau mentioned 👍

Was this page helpful?
0 / 5 - 0 ratings

Related issues

nicoasp picture nicoasp  ·  3Comments

TobiahRex picture TobiahRex  ·  3Comments

Loriot-n picture Loriot-n  ·  4Comments

Chrischuck picture Chrischuck  ·  3Comments

wooyah picture wooyah  ·  4Comments