Skip to content

fix(facebook): map (#200) permission errors to a curated message - #1892

Merged
giladresisi merged 3 commits into
mainfrom
fix/facebook-200-permission-mapping
Sep 16, 2026
Merged

giladresisi merged 3 commits into
mainfrom
fix/facebook-200-permission-mapping

Conversation

@giladresisi

@giladresisi giladresisi commented Aug 14, 2026 •

Copy link
Copy Markdown
Collaborator

What kind of change does this PR introduce?

Bug fix / UX improvement

Why was this change needed?

A customer's Facebook Page posts were failing 100% of the time with a Graph API OAuthException, code 200: (#200) ... requires both pages_read_engagement and pages_manage_posts as an admin with sufficient administrative permission. This happens when the connected Facebook account lacks posting rights on the Page (insufficient page role, or pages_manage_posts unchecked in the granular OAuth dialog) — reconnecting alone doesn't fix it, the user has to fix their page access on Facebook first.

Because FacebookProvider.handleErrors had no mapping for it, the failure surfaced as the Unknown Error placeholder — the failure email told the customer nothing, and they had no way to self-serve.

This adds a curated bad-body mapping on the (#200) marker:

Facebook rejected the post due to missing permissions. Make sure your Facebook account has full content access to the Page, then reconnect the channel.

Per Meta's error-handling docs, codes 200–299 are "API Permission" errors, so (#200) always denotes a permissions problem — the mapping can't mislabel an unrelated failure. The reverse isn't 1-1 (other permission errors use other codes, e.g. 10 or the rest of 200–299; see also this writeup on error 200 causes); those still fall back to the generic message, same as today.

With this mapping, the failure email immediately shows the actionable message, and once #1868 (curated calendar error tooltips) merges, the calendar tooltip surfaces it too — so the user can self-serve: fix their Page access on Facebook, reconnect, repost.

Side effect: the isPresetRejection retry helper matches 'Unknown Error', so a (#200) failure on a preset post previously triggered a pointless second publish attempt without the preset; with the curated message it no longer does.

Update — Instagram too (cd1e40d): the same (#200) body also shows up on the Instagram (Facebook-login) provider, where publishing goes through the Facebook Page linked to the Instagram account (5 occurrences in production since 2026-07-01, all previously surfaced as Unknown Error). InstagramProvider.handleErrors now maps it the same way (non-retryable bad-body, message adjusted to point at the linked Page), placed before the generic '190,' rule; instagram-standalone delegates to the same handleErrors, so it is covered as well.

Other information:

Verified against production data: the failing page had 16/16 posts rejected with this exact error body, including after a fresh reconnect, confirming it's a page-access problem the user must resolve on Facebook's side.

Checklist:

  • I have read the CONTRIBUTING guide.
  • I have signed the Contributor License Agreement (CLA).
  • I confirm I have not used AI to submit this PR or generate code for it.
  • I checked that there were no similar issues or PRs already open for this.
  • This PR fixes just ONE issue

🤖 Generated with Claude Code

Facebook rejects page publishes with an OAuthException code 200 when the
connected account lacks pages_manage_posts / pages_read_engagement or
sufficient page role. This previously fell through handleErrors to the
'Unknown Error' placeholder, so the failure email (and, once merged, the
curated calendar tooltip from #1868) showed nothing actionable.

Per Meta's docs, codes 200-299 are API Permission errors, so the (#200)
marker always denotes a permissions problem. As a side effect, the preset
retry helper no longer treats these as 'Unknown Error', avoiding a wasted
second publish attempt.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@postiz-contribution postiz-contribution Bot added the contribution:approved Approved contributor label Aug 14, 2026
@postiz-agent

postiz-agent Bot commented Aug 14, 2026 •

Copy link
Copy Markdown

✅ Snyk checks have passed. No issues have been found so far.

Status Scan Engine Critical High Medium Low Total (0)
✅ Open Source Security 0 0 0 0 0 issues
✅ Licenses 0 0 0 0 0 issues
✅ Code Security 0 0 0 0 0 issues

💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse.

The same Graph (#200) OAuthException surfaces on the Instagram
(Facebook-login) provider when the connected user lacks sufficient
permissions on the Facebook Page linked to the Instagram account. Map it
the same way as in the Facebook provider (non-retryable bad-body), placed
before the generic '190,' rule; instagram-standalone delegates to the same
handleErrors.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@strix-security

strix-security Bot commented Aug 18, 2026 •

Copy link
Copy Markdown

Strix Security Review

No security issues found.

Updated for 522a0f4.


Reviewed by Strix
Re-run review · Configure security review settings

@postiz-contribution
postiz-contribution Bot changed the base branch from staging to main September 15, 2026 08:19
@giladresisi
giladresisi added this pull request to the merge queue Sep 15, 2026
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to a conflict with the base branch Sep 15, 2026
…ission-mapping

# Conflicts:
#	libraries/nestjs-libraries/src/integrations/social/facebook.provider.ts
@giladresisi
giladresisi added this pull request to the merge queue Sep 16, 2026
Merged via the queue into main with commit 0a4301e Sep 16, 2026
12 checks passed
@giladresisi
giladresisi deleted the fix/facebook-200-permission-mapping branch September 16, 2026 01:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant