Troubleshooting
HTTP requests are not enabled
Symptom: Transport errors with statusCode = 0. Fix: Studio → Game Settings →
Security → Allow HTTP Requests.
401 / 403 (Auth)
The API key is missing, wrong, revoked, or expired — not retried. Recreate
the key in the dashboard and update ServerStorage/RoControlConfig/ApiKey. The
backend derives the universe from the key, so a key only works for its own game.
429 (Rate limited)
The SDK retries automatically, honoring Retry-After, with backoff + jitter. If
it persists, you’re likely calling reportEvent too often — prefer a declarative
schedule, and confirm enableMemoryStoreLease = true so only one server reports
each occurrence.
409 (Idempotency conflict)
The same idempotency key was reused with a different request body. This usually
means two servers built different payloads for the same occurrence — ensure your
occurrenceId (and schedule descriptor) is deterministic across servers.
Circuit breaker open
After repeated retryable failures the SDK opens the circuit for a cooldown and
returns circuit_open. It recovers automatically. Inspect client:getHealth().
MemoryStore unavailable
The SDK logs lease_unavailable, falls back to a per-server debounce, and relies
on backend idempotency. No action needed — reports are still de-duplicated, you
may just see a few more requests.
Moderation
Every icon change passes Roblox moderation. RoControl re-submits only when the
winning overlay actually changes, resolves and caches the asset image, and records
moderation status (pending/approved/rejected/failed) on the Icon
Automation state. Rejected/invalid assets are surfaced in the dashboard instead
of being retried in a loop — fix the asset and report again.
Nothing appears in the dashboard
- Confirm the bootstrap runs on the server (ServerScriptService).
- Set
logLevel = "debug"and look for request logs (secrets are redacted). - Verify
baseUrland that the key’s universe matches the place. - Check
client:getHealth()for circuit state and last success/failure.