Troubleshooting: template fallback variant missing
APOST /messages/content-templates create failed with HTTP 400 and the
error message:
fallback_chain that have no variant in its variants map. The named
fallback variant is missing — the chain entry promises a substitute that
was never authored. Orbit refuses to save the template rather than let a
declared-but-unrendered fallback channel surface later, at send time, as
an unexpected resolve failure.
Why the guard fires at authoring time
A fallback chain is a promise: “when the target channel has no variant, try these channels in order.” A chain entry for a channel nobody authored a variant for cannot honour that promise. If the create succeeded, the orphan entry would sit in the chain until a render or send walked to it, skipped it (a chain hop with no variant resolves nothing), and either jumped to a later hop or failed the request with the 422NO_VARIANT_FOR_CHANNEL error — depending on whether anything after it
resolved.
The create-time check turns that latent failure into an immediate,
explicit one. The error message lists every orphaned channel, so the
payload you sent and the fix are in the same round trip.
Find the orphaned entries
Compare the two parts of your own payload:variantsis a map keyed by channel name — its keys are the only channels the template actually covers.fallback_chainis an ordered list of channel names — every entry must appear as a key invariants.
variants key is named in the error
message after channels with no variant:. The check compares the
payload you sent, not the stored template — on a create, fix the payload
before you retry.
The same gap can also appear on a template that was created before this
guard existed, or introduced by a later partial update that replaced
variants or fallback_chain separately. Fetch the template
(GET /messages/content-templates/:id) and diff variants keys against
fallback_chain — every chain entry must have a variant.
Fix it one of two ways
Pick the fix that matches your intent:- Author the missing variant. The fallback entry was deliberate —
you want the substitute. Add the variant for the named channel to the
variantsmap, with the channel-rendered copy it needs (componentsfor WhatsApp,subject+body_htmlfor email,bodyfor SMS), then re-send the create or runPATCH /messages/content-templates/:id. - Remove the orphaned entry from the chain. The entry was a mistake —
nobody plans to author that channel. Drop it from
fallback_chainand keep the chain entries that do have variants. The chain walks in order, so check the surviving entries still give you the substitute order you want.
Confirm the fix with a render
Once the template saves, prove the chain actually resolves by rendering against a channel the template does not cover:- Run
POST /messages/content-templates/:id/renderwithtarget_channelset to a channel absent fromvariants. - The response’s
rendered_channelshould be the first fallback-chain entry that has a variant, andresolutionshould be"fallback". - If the response is instead a 422
NO_VARIANT_FOR_CHANNEL, the chain still does not resolve — see template variant missing for the resolve-time side of this error family.
Where this usually goes wrong
- Chain updated, variants not. A partial update replaced the chain with one that names a channel whose variant was never written. Diff the two maps whenever either changes.
- Variant removed, chain left behind. Deleting a variant (rewriting
variantswithout a channel) while its name stays infallback_chainrecreates the orphan on an older template. default_channelin the same boat. Create also rejects adefault_channelthat has no variant in the payload. The fix is the same: author the variant or point the default at a covered channel.
See also
- Template variant missing (NO_VARIANT_FOR_CHANNEL) — the 422 resolve-time counterpart: the request succeeded but no channel resolved.
- Content templates API — the create, update, and render endpoints, with request schemas.
- Error code reference — the registry entries
for
VALIDATION_ERRORandNO_VARIANT_FOR_CHANNEL.