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}

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.

Related guides

Run this faster and cheaper on Latchkey managed runners. Start free →