LINE Messaging API · error code

LINE error 400: The request body has X error(s)

Permanent - do not retryHTTP 400400 / 409 / 413: request body, tokens and payload

Last verified against LINE Developers - Messaging API reference (error responses)

What LINE returns
The request body has X error(s) <detail varies>

What error 400 means

LINE parsed your JSON successfully but found one or more validation failures in it, and the number of failures replaces the X. This is the workhorse 400 of the Messaging API and the one error where LINE tells you precisely where to look: the reference says "further details are shown in the details[].message and details[].property properties." Each element of details is one fault - property is the JSON path of the offending field (messages[0].text, areas[0].action.uri), and message is the rule it broke (May not be empty, invalid uri, or an enumeration of allowed values).

Read the details array before anything else; debugging this error from the top-level message alone is guesswork. The array indexes map one-to-one onto your messages array, so messages[1].type means the second message object in the request. Common rule families you'll see quoted in details[].message: required properties that are empty or missing, values outside an allowed enum, strings over their character caps (text messages cap at 5,000 characters counted in UTF-16 code units - see text limits), arrays over their size caps (more than 5 message objects per request, more than 13 quick reply items, more than 12 bubbles in a Flex carousel), and malformed or non-HTTPS URLs in properties that require "HTTPS (TLS 1.2 or later)".

Two quota-related distinctions: this error means the request never sent anything, so nothing was charged; and it is deterministic - the same body will fail the same way every time, so retrying without changing the payload is pointless. If your JSON is so broken it can't be parsed at all, you get The request body could not be parsed as JSON instead, and a wrong Content-Type header produces The content type, XXX, is not supported.

What it looks like

{
  "message": "The request body has 2 error(s)",
  "details": [
    {
      "message": "May not be empty",
      "property": "messages[0].text"
    },
    {
      "message": "Must be one of the following values: [text, image, video, audio, location, sticker, template, imagemap]",
      "property": "messages[1].type"
    }
  ]
}

Why it happens

  • A required property is empty or missing - the classic details entry is "May not be empty" on messages[0].text.
  • A property value is outside its allowed set, e.g. an unknown message type, an invalid action type, or a bad URI scheme ("invalid uri").
  • A character or size cap was exceeded: 5,000 characters of text, 1,500 characters of altText, 2,000 characters for a URL, 5 message objects, 13 quick reply items, 12 carousel bubbles.
  • An image, video, or audio URL uses plain http:// - media URLs must be HTTPS with TLS 1.2 or later.
  • Text with LINE emojis grew past the limit after the $ placeholder was replaced with the emoji's undisclosed alternative text.
  • A number was sent as a string or vice versa, or a nested object (quickReply, flex contents) doesn't match its documented schema.

How to fix LINE error 400

  1. 1Log the full error body, not just message - iterate over details[] and print property with message for each entry.
  2. 2Open the exact JSON path from details[].property in your request payload and compare the value against the field's spec in the Messaging API reference.
  3. 3Count characters the way LINE does - UTF-16 code units, where emojis and some Kanji count as two - before trusting your own length checks.
  4. 4Validate without sending: POST the same messages array to the validate endpoints (e.g. /v2/bot/message/validate/push or /validate/reply), which run the same object validation free of charge and quota.
  5. 5For Flex Messages, check JSON size against the caps (30 KB per bubble, 50 KB per carousel) and test the payload in LINE's Flex Message Simulator.
  6. 6Re-send only after the payload changes - the error is deterministic and retries with the same body will fail identically.

How to stop it recurring

Build message objects through one shared constructor that enforces the documented caps (text, Flex sizes, quick reply) rather than assembling JSON ad hoc, and wire the free validate endpoints into CI for every template you ship. Truncate user-generated text in UTF-16 code units with margin for LINE emoji alternative text, and reject non-HTTPS media URLs at input time.

Official reference: LINE Developers - Messaging API reference (error responses). See all LINE error codes or the LINE limits and quotas.

Related codes

Error 400 - quick answers

What does LINE error 400 mean?

LINE parsed your JSON successfully but found one or more validation failures in it, and the number of failures replaces the X .

How do I fix LINE error 400?

1. Log the full error body, not just message - iterate over details[] and print property with message for each entry. 2. Open the exact JSON path from details[].property in your request payload and compare the value against the field's spec in the Messaging API reference. 3. Count characters the way LINE does - UTF-16 code units, where emojis and some Kanji count as two - before trusting your own length checks. 4. Validate without sending: POST the same messages array to…

Should I retry after error 400?

No. Retrying the same request produces the same error; the condition has to be fixed first. Treat it as a permanent failure for that message and surface it, rather than looping.

Stop debugging LINE by hand

Connect the channel through Conferbot: tokens, webhooks and retries are handled, failures show as readable status.