SendGrid 400 Bad Request (malformed mail/send) in CI
SendGrid returns HTTP 400 with a specific errors array when the mail/send body is structurally valid JSON but violates the schema, for example a missing content, an empty subject, or a personalizations block with no recipient. The message names the offending field.
What this error means
A SendGrid mail/send call returns HTTP 400 with an errors array pointing at a field like content or personalizations.0.to. No email is sent.
< HTTP/2 400
{"errors":[{"message":"The content value must be one or more valid content objects.","field":"content","help":null}]}Common causes
A required field is missing or empty
mail/send requires at least one personalizations recipient, a subject, and a non-empty content array. An empty commit summary can blank the content.
Wrong field types after templating
Building the JSON by string concatenation can put a scalar where an array or object is required.
How to fix it
Build a complete payload with jq
- Read the field named in the 400 response.
- Ensure
content,subject, and a recipient are all present and non-empty. - Construct the JSON with jq so types are correct.
body="${SUMMARY:-CI run completed}"
jq -n --arg b "$body" '{
personalizations:[{to:[{email:"team@example.com"}]}],
from:{email:"ci@your-verified-domain.com"},
subject:"CI result",
content:[{type:"text/plain",value:$b}]}' > mail.jsonDefault empty values
Guard against an empty subject or body so the schema is always satisfied.
[ -n "$SUMMARY" ] || SUMMARY="CI run completed"How to prevent it
- Validate the mail/send JSON shape before sending.
- Default the subject and body so required fields are never empty.
- Build payloads with jq rather than string concatenation.