Troubleshoot template composition errors
Before a template message goes out, Orbit renders the final payload (variables substituted, buttons resolved) and checks every component against the limits Meta (WhatsApp) and Google (RCS) enforce on the wire. Anything a provider would reject comes back in the preview’scomposition_errors array, one entry per problem, each naming the offending field, a code, and a readable message:
OVER_LENGTH— a text component exceeds its character cap.INVALID_BUTTON— a BUTTONS component is empty or over-counted, a label is over-long, or a button type is one Meta does not accept.INVALID_COMPONENT— a component format or component mix Meta does not define (unknown HEADER format, missing or duplicated BODY).
Where you see these codes
In the template dialog. The create/edit template dialog runs the preview on your draft as you type and surfaces any open composition errors before you submit. While an error is open nothing is submitted: no send is attempted, nothing is queued, and no credit is debited. Fix the field and the error clears on the next preview pass. In the messages preview API. The samecomposition_errors array returns from the preview render endpoint, alongside unresolved_variables, unused_variables, and an ok flag. Automation that assembles template payloads should treat ok: false as “do not queue yet” and surface field plus message to whoever owns the copy.
Caps are measured after variable substitution. A 900-character BODY whose {{1}} resolves to a 300-character value is over 1,200 characters and fails OVER_LENGTH even though the draft text fits. Check the rendered length, not the draft length, when a template only overflows for some recipients.
OVER_LENGTH — a component exceeds its cap
Thefield value names the exact component:
INVALID_BUTTON — the BUTTONS component or a button is malformed
INVALID_COMPONENT — a component shape Meta does not define
The limits, in one table
All character counts are post-substitution, measured the same way the preview and the send path measure them.
WhatsApp applies caps per component, not to the message as a whole. A template
can carry 60 + 1,024 + 60 characters across HEADER, BODY, and FOOTER plus button
labels; no single component may exceed its own cap.
unresolved_variables vs unused_variables
The preview returns two arrays next tocomposition_errors that describe your variable wiring rather than your component shapes:
unresolved_variables— placeholders the template references but yourvariablesdid not cover ({{1}},{{first_name}},{{contact.custom.tier}}). The rendered payload keeps the literal token, so the recipient would receive{{first_name}}verbatim; the preview therefore keepsokfalse until every token resolves. Fix: supply the missing key, or fix the token spelling in the template.unused_variables— values you supplied that no placeholder references. This one is advisory and does not blockok: nothing breaks, but a key landing here is usually the other half of a typo (you sentfirst_name, the template saysfirstname). Fix: drop the extra key or correct the placeholder it was meant to fill.
When the provider still rejects
Templates saved before these checks existed, or written straight through the API without a preview pass, can hold over-length or malformed payloads that only surface at delivery time:- Meta (WhatsApp) rejects the send with
error_subcode 2388042when a stored component exceeds a cap or carries a bad shape. Re-open the template in the dialog to run the preview over the stored payload, trim to the caps above, and resubmit for approval as described in Create and approve WhatsApp templates. - Google RBM (RCS) answers
INVALID_ARGUMENTfor the same class of problem on rich cards and suggestions; the RCS limits above and Build RCS rich cards cover the accepted shapes.
- WhatsApp template variable count mismatch — the send-side pre-flight on
template_paramscount vs{{N}}placeholders, a 400 before the request reaches Meta. - Template has no variant for the channel — the routing layer cannot find a variant for the channel you are sending on.
- SMS segments and encoding — how GSM-7 vs UCS-2 text maps body length to billed segments.