Async engine write gotchas
Retrying a stalled OnlyFans write the wrong way can create a duplicate on OnlyFans instead of finishing the original.
Every write that reaches OnlyFans through Club's engine — vault folder ops, vault uploads, promo
campaigns and bundles — follows the same shape: the API answers {"status": "pending", "nonce": "..."} immediately, and a background reconciler confirms the real outcome later. See
Pending-nonce job durability
for why. Two gotchas fall directly out of that design.
Retrying the wrong way mints a duplicate
A job only dedups against another submission while it's still queued or inflight. Once
it settles — done, failed, or stale — a fresh call to the same create endpoint is treated
as a brand-new request with a brand-new nonce. stale in particular does not mean "definitely
didn't happen" — the engine could have crashed on OnlyFans' side of the call, after the write
already went through. Retry a stale/failed create the wrong way, and if the original attempt
actually landed, you now have two live campaigns, bundles, or folders on OnlyFans.
Vault folder ops have a safe retry path — promo does not
POST /vault/ops/{nonce}/retry re-submits a vault folder operation under the same nonce,
specifically to avoid this. Promo campaigns and bundles (POST /promo/campaigns,
POST /promo/bundles) have no equivalent retry endpoint — there is only
GET /promo/ops/{nonce} to poll status. If a promo/bundle create comes back stale, check
OnlyFans directly (or wait for the next capture sync) before deciding whether to submit again.
A "not doing anything" button is usually a fail-closed gate, not a bug
Vault folder ops and vault uploads answer {"enabled": false, "staged": true} instead of
queuing anything whenever the engine hasn't reported itself alive recently enough — its
manifest is missing, in the wrong mode, or its promised next check-in has already passed (with a
15-minute slack built in for clock drift and poll duration). This is deliberate fail-closed
behavior: the backend has no way to confirm the engine will actually pick up a queued job, so it
refuses to pretend one was queued.
| Symptom | Where to look |
|---|---|
Folder create/rename/delete or add/remove-media returns {enabled:false, staged:true} | The engine's vault_ops manifest is stale/missing, or the panel-side vault_write_ready switch is off. |
The upload button is greyed out, or POST /vault/upload returns {enabled:false, staged:true} | Same shape, two independent switches: the panel's vault_upload_ready flag and the engine's own upload-lane manifest both have to be live. |
Neither of these is a broken button — they're an honest "the engine isn't confirmed reachable right now", checked before anything is queued.
What's next
For the export-side gate (why a bulk read sometimes demands 2FA), see Vault DLP export gates.
Naming collisions to not conflate
Same-sounding names, different things — a third-party "Chatter" API that isn't your team, two unrelated PPV pricers, and two smart-link systems with near-identical filenames.
A fan's card shows another page's data
Why the same fan_id can render one page's money and DMs under another page's name — and the fail-closed header that stops it.