#Edge-case matrix
For each case: trigger → backend response → frontend behaviour → user message → recovery. Status codes follow the OSS conventions where Central has no API yet Assumption. Messages are i18n keys in the build (the English shown is the source text).
| # | Case | Trigger | Backend response | Frontend behaviour | User message | Recovery |
|---|---|---|---|---|---|---|
| 1 | Invalid login | Wrong email/password | 422/401 generic | Clear password, focus it | "Incorrect email or password." | Retry / forgot password |
| 2 | Unverified account | Login before verifying | 403 code: unverified | Show resend button | "Please verify your email first." | Resend link |
| 3 | Banned / locked | Login | 403 code: banned | No retry | "This account is locked. Contact support." | Support |
| 4 | Unknown IP (whitelist on) | Login from a new IP | 403 code: ip_not_approved | Approval-sent screen | "We emailed you a link to approve this IP." | Click link (24 h) |
| 5 | 2FA wrong code | Bad code | 422, attempts left | Shake + counter | "That code is wrong. N tries left." | Resend / backup code |
| 6 | Session expired | Token expired | 401 | Refresh once, else to login | "Your session expired. Please log in again." | Log in → return to next |
| 7 | No organization | Login with none | 200 empty list | Route to create organization | "Create your organization to get started." | Create |
| 8 | Organization deleted | Current org gone | 404 on scoped calls | Clear current, switch to main/first | "That organization is no longer available." | Pick another |
| 9 | Member removed | Membership revoked | 403/404 | Same as 8 | "You no longer have access to | Ask an owner |
| 10 | Permission denied | Action without grant | 403 code: forbidden | 403 state / toast, refresh permissions | "You don't have permission to do this." | Ask an owner |
| 11 | Plan expired | Subscription expired | 403 code: subscription_expired (V7 sends 500 + message) | Banner, actions disabled | "Your subscription has expired. Renew to continue." | Renew |
| 12 | Subscription cancelled | Cancel flag set | 200 status cancelled | "Ends on | "Your plan ends on | Resume |
| 13 | Payment failed | Gateway declined | Transaction failed | Return page shows failure | "The payment didn't go through. Nothing was charged." | Retry / other method |
| 14 | Payment pending | Gateway slow | Transaction pending | Poll, then "processing" | "We're confirming your payment. This can take a few minutes." | Wait / email |
| 15 | Not enough credit | Plan change > balance | 422 code: insufficient_credit + amount | Show top-up with the amount | "Add $N to your wallet to continue." | Top up |
| 16 | Usage limit reached | Add server over limit | 403 code: plan_limit_reached | Upgrade dialog | "Your plan allows N servers." | Upgrade / disconnect |
| 17 | Server offline | OSS timeout | 504 code: server_unreachable | Unreachable state | "This server isn't responding (last seen …)." | Retry / check server |
| 18 | Invalid key | OSS 401 on connect | 422 code: invalid_server_key | Field error | "This Central key isn't valid." | Copy the key again |
| 19 | Key revoked later | OSS 401 on use | 409/424 code: server_unauthorized | Reconnect banner | "Central can no longer access this server." | Paste the new key |
| 20 | Duplicate server | Already linked | 409 code: server_already_connected | Field error | "This server is already connected." | Open the existing one |
| 21 | Version mismatch | OSS older than minimum | 422 code: oss_version_unsupported | Explain + docs link | "Update the panel to vX.Y or newer." | Update the panel |
| 22 | Provider failure | Provider API error | 502 code: provider_error + provider message | Keep the form | " | Fix / retry |
| 23 | Provider token expired | OAuth expired, refresh failed | 401 code: provider_reauth | Reconnect button | "Reconnect your | OAuth again |
| 24 | VPS creation failure | Create/boot/install failed | Job status failed + step | Progress shows the failed step | "Server creation failed at | Retry / delete VPS |
| 25 | Blueprint deployment failure | Add-on run failed / steps failed | Run failed or completed: false | Per-step results | "Blueprint finished with N failed steps." | Retry / edit |
| 26 | Add-on not installed / no licence | OSS 404/403 add-on codes | Passed through | Install/buy hint | "WP Toolkit isn't installed / licensed on this server." | Install / buy |
| 27 | API timeout | Central slow | Client timeout | Error state + retry | "This is taking too long." | Retry |
| 28 | Network error | Offline | No response | Offline banner, keep form data | "You appear to be offline." | Retry when online |
| 29 | 404 | Wrong URL / other org's resource | 404 | not-found page | "This page doesn't exist." | Back / dashboard |
| 30 | 500 | Bug | 500 + reference | Error state + reference | "Something went wrong. Reference: …" | Retry / support |
| 31 | 429 | Too many requests | 429 + Retry-After | Disable action, countdown | "Too many requests. Try again in N s." | Wait |
| 32 | Concurrent edit | Two admins edit a role | 409 or last-write-wins Open question | Reload prompt | "This was changed by someone else." | Reload |
| 33 | Owner removes self / last owner | Remove member | 422 | Refuse | "An organization needs an owner." | Transfer ownership Open question |
| 34 | Delete org with servers | Delete | 422 (V7: 500 + message) | Link to servers | "Disconnect all servers first." | Disconnect |
| 35 | Delete protection on | Any delete | 403 code: delete_protection | Explain the setting | "Delete protection is on." | Turn it off in Security |
| 36 | Invitation expired / used | Open the link | 410/404 | Invite-invalid page | "This invitation is no longer valid." | Ask for a new invite |
| 37 | Locale missing | Key not translated | — | English fallback | (English text) | Translate |