Troubleshooting: Messenger channel not connected
A Messenger channel write or persona operation returns 409MESSENGER_NOT_CONNECTED when Meta is missing a valid connection
for the channel the request targets. On the Messenger lane it fires
on the persona calls — list, create, delete — whenever the stored
connection is marked disconnected or it carries no Page access token
at all. Refusing the call instead of sending it to Meta is
intentional: persona operations would fail at Meta with a far less
readable error if Orbit forwarded them without a token.
The 409 is a connection-state refusal, not a permission or
validation failure — no amount of request reshaping fixes it. Only
reconnecting the Page flips the condition the guard reads.
When the 409 fires
The guard reads the connection row for the Messenger channel, and
any caller that resolves the stored Page access token routes through
it — so the list/create/delete surface is the whole persona
surface.
Read the sibling codes off the same refusal class — they route to
different fixes:
Routing by the error envelope
The envelope carries the channel under a structured detail, so a blocked writer routes readers by the exact code:MESSENGER_NOT_CONNECTED, and the fix is identical
either way — so this particular code needs no channel branch.
Sibling channels DO split it — LINE’s LINE_NOT_CONFIGURED is a
settings-completeness refusal, where a raw token/email config is
absent, and other channels branch NOT_CONNECTED from
CONNECTION_INVALID. Routing code should read
details.channel_id before lumping every refusal onto
“reconnect.”
Diagnose: confirm the channel is really disconnected
Check either surface before touching OAuth — some disconnected reports turn out to beMESSENGER_TOKEN_UNREADABLE, which needs the
same reconnect but starts from a different envelope, so confirm the
code you actually got.
-
Dashboard surface. Open Settings → Channels → Messenger.
The status badge reports
disconnected(noconnectedmark) orexpired(token present but past its rotation window) — either routes into the reconnect flow below. -
API surface. Read the channel-status surface:
For the Meta-adjacent channels the richer connected/token view (valid / expiring_soon / expired) rides on this endpoint. A disconnected channel reports the connection as absent; a
MESSENGER_TOKEN_UNREADABLE-class channel still reports a token but the endpoint cannot vouch for its decryptability.
Fix: flip the channel back to connected
Two self-serve reconnect paths replace the stored token with a fresh, correctly scoped one. Pick OAuth (recommended) or the scope-repair flow when your company’s Meta app-review approves fewer scopes than the Page picker requests.Path A — OAuth reconnect with the Page picker
The full ordering is on the Messenger channel page; condensed for this recovery:- In Settings → Channels → Messenger, click Reconnect.
- Meta’s OAuth dialog re-opens; re-select the Page you were using (the dialog lists Pages you administer).
- Outbound sends and persona operations resume as soon as the stored token is replaced.
Path B — re-attach the required Meta scopes
If the OAuth dialog completes but the channel still refuses with the 409, the scopes granted to the Meta app were narrowed. Re-run the dialog with both scopes checked (per the channel page’s required-scopes list):
Re-running the dialog with both scopes re-selected flips the stored
row back and the 409 stops.
Confirm the flip
The condition the guard checks is the connection row havingconnected plus a stored Page access token. After either path,
re-read the channel status — a healthy reconnect reports the
channel as connected with the token valid (or expiring_soon; that
still satisfies the guard — the 409 fires only on absent).
Then retry the refused personas call once. Do not loop it against
the 409: the refusal is deterministic, and a loop re-reads the same
guard on every attempt.
Distinguish from the not-configured family
Sibling channels split “nothing has ever been set up” into a*_NOT_CONFIGURED code (412) instead of *_NOT_CONNECTED (409).
The distinction is bookkeeping, not severity, and it matters only
to routing code: the NOT_CONFIGURED family means the tenant’s
settings payload never carried that channel at all (self-serve:
store the credential), while NOT_CONNECTED means a channel row
exists but the connection guard reads it as disconnected
(self-serve: reconnect). Route on details.channel_id before
picking a remediation, and never treat a NOT_CONFIGURED as a
reason to re-OAuth something that was never set up.
When NOT to retry
- Do not retry the same personas request. Every retry hits the same guard and returns the same 409 until a reconnect lands.
- Do not retry with a different persona name or avatar. The refusal fires before any persona data is read; nothing in your request body can steer around it.
- Do not create new personas while disconnected. The guard refuses list/create/delete identically; the read side also 409s.
Escalation checklist
Open a ticket when the channel status reports connected, the OAuth dialog completed with both scopes, and the personas call still 409s. Include:- The
request_idfrommetaon the 409. - The exact endpoint you were calling (list, create, or delete).
- The channel status snapshot (dashboard badge or the API read).
- The code you received —
MESSENGER_NOT_CONNECTEDvsMESSENGER_TOKEN_UNREADABLEsplits the follow-up.
See also
- Messenger channel page — full onboarding ordering, required scopes, persona limits, and the error table this code is a row of
- Troubleshooting: WhatsApp connection and
re-authentication — the
sibling page where the connected / token-unreadable split sits at
NOT_CONNECTEDvsCONNECTION_INVALIDinstead of 409 on both - Troubleshooting: Messenger 24-hour window closed — the send-side sibling in the Messenger error family
- Error Code Reference — every code in the messaging family, in one table
- Troubleshooting hub — every runbook in one index