Skip to content
Latchkey

Discord webhook 400 "Cannot send an empty message" in CI

Discord returns HTTP 400 with {"code":50006,"message":"Cannot send an empty message"} when a webhook payload contains no content, no embeds, and no files. In CI this happens when the message is built from a variable that turned out empty.

What this error means

The Discord notify step gets HTTP 400 with message Cannot send an empty message. It often fails only when a commit message, job status, or template variable resolves to an empty string.

Discord API
< HTTP/1.1 400 Bad Request
{"message": "Cannot send an empty message", "code": 50006}

Diagnose it: produced, uploaded, or mapped?

Third-party integrations fail at one of three points, and the symptom is the same for all of them: the report was never produced, the upload was rejected, or the service could not map the paths back to your repository.

Terminal
ls -la <report-dir>/ && head -5 <report-file>
grep -c . <report-file> || echo "empty report"
# absolute paths in a report break server-side file mapping
grep -m3 -E "^(SF:|<file)" <report-file>

Common causes

An interpolated value was empty

A content built from an unset environment variable or a job output that did not populate leaves the payload with nothing to display.

Only unsupported fields were sent

A payload with keys Discord ignores, and no content/embeds/files, counts as empty.

How to fix it

Guard against an empty message

  1. Compute the message text first.
  2. Substitute a default when it is empty.
  3. Send content that is guaranteed non-empty.
Terminal
msg="$(git log -1 --pretty=%s)"
msg="${msg:-CI run completed}"
payload=$(jq -n --arg c "$msg" '{content:$c}')
curl -sS -X POST -H 'Content-Type: application/json' \
  --data "$payload" "$DISCORD_WEBHOOK_URL"

Send an embed with a title as a fallback

An embed with a title counts as non-empty even if the description is blank.

JSON
{"embeds":[{"title":"CI result","description":"build passed"}]}

How to prevent it

  • Default the message text before building the payload.
  • Validate that content or embeds is non-empty in the notify script.
  • Encode interpolated values with jq to avoid quoting surprises.

Frequently asked questions

What causes Discord webhook 400 "Cannot send an empty message" in CI?
There are 2 common causes: an interpolated value was empty and only unsupported fields were sent. A content built from an unset environment variable or a job output that did not populate leaves the payload with nothing to display.
How do I fix Discord webhook 400 "Cannot send an empty message" in CI?
There are 2 fixes depending on which cause you have: guard against an empty message and send an embed with a title as a fallback. Work through them in order, since the first is the most common.
What does Discord webhook 400 "Cannot send an empty message" in CI actually mean?
The Discord notify step gets HTTP 400 with message Cannot send an empty message.
How do I stop Discord webhook 400 "Cannot send an empty message" in CI happening again?
Default the message text before building the payload. The prevention section lists 3 changes that keep it from recurring.

Related guides

References

Not every red build is your code. Latchkey repairs the ones that are not, on the runner. Start free → 30-day trial · No credit card