# Troubleshooting

| Symptom | Likely cause | Fix |
|---|---|---|
| `check-requirements.php` FAIL on an extension | Not enabled for the PHP version | cPanel → Select PHP Version → Extensions (or MultiPHP for the CLI version) |
| `kaabe:install`: "Central database connection" FAIL | Wrong `DB_*`, or user not added to the database | cPanel → MySQL Databases → *Add User To Database*, ALL PRIVILEGES |
| `kaabe:install`: "PHP command line works" FAIL | CLI PHP is not 8.2+ | Set `KAABE_PHP_BINARY=/opt/cpanel/ea-php83/root/usr/bin/php` (**VERIFY ON INMOTION**) |
| `kaabe:install` says already installed | Lock file present | Intended. For a clean reinstall only: drop the central tables, then delete `platform/storage/app/kaabe-installed.lock` |
| `build-platform.sh`: cannot download | No outbound HTTPS | Use `scripts/build-platform-docker.sh` on a PC (`DEPLOYMENT-INMOTION-CPANEL.md` §4) |
| Admin shows "500 Server Error" | Error logged | `tail -50 ~/kaabe/platform/storage/logs/laravel-$(date +%F).log`, then fix. Never switch `APP_DEBUG` on in production |
| Admin 403/404 on every page | Document root not `platform/public`, or `mod_rewrite` off | cPanel → Domains → document root |
| POS: "Business not found" | Sub-domain not in the registry, or the domain is not pointed at `kaabe/pos` | Check the business is not draft; `php artisan kaabe:registry`; check the document root |
| POS: "Temporarily unavailable" | Registry path or key wrong in `pos/kaabe/.env` | Same `KAABE_REGISTRY_PATH` and `KAABE_REGISTRY_KEY` as the platform; `private/tenants.php` exists |
| POS: "The action you have requested is not allowed" | CSRF token missing on a screen | Report the screen. Temporary switch: `KAABE_CSRF=0` in `pos/kaabe/.env` (re-enable afterwards) |
| Provisioning failed at "database" | cPanel token, prefix or limit | Read the provisioning log; check `CPANEL_*`, `KAABE_DB_PREFIX`, and the database limit (`uapi StatsBar …`); then *Retry provisioning* |
| Provisioning failed at "schema" | `mysql` client path, or a half-loaded database | Set `KAABE_MYSQL_BINARY`; for a half-loaded database use *Reset database*, then *Retry* |
| Provisioning failed at "migrations" | `proc_open` disabled, or wrong `KAABE_PHP_BINARY` / `KAABE_POS_PATH` | `check-requirements.php` |
| Sync failed / delayed alerts | Business database unreachable or password changed | Business → Connection → *Test*; `php artisan kaabe:sales-sync <slug>` shows the error |
| Nothing happens on schedule | Cron missing or PHP path wrong | cPanel → Cron Jobs; run the cron line by hand in the Terminal |
| Plan change not visible in the POS | Registry/opcache delay or queue not running | Wait 1–2 minutes; `php artisan kaabe:sync <slug> --force` |

## Found during 1.0.0 testing
| Symptom | Cause | Fix |
|---|---|---|
| Provisioning fails at "grant" with *Access denied* (direct mode) | provisioning account lacks `WITH GRANT OPTION` on `<prefix>t%`, or the grant pattern was written with an escaped underscore (`kaabe\_t%`) – use `kaabe_t%` | see `INSTALLATION.md` §4b; check `SHOW GRANTS`; then Business → Provisioning → *Retry* |
| "You do not have the feature mysql" | cPanel API token/account without the MySQL Databases feature | ask InMotion / use a token of the main cPanel account; *Retry* |
| Business stays "pending" | cron not running (`schedule:run`) | check Cron Jobs; `php artisan queue:work --stop-when-empty` |
| POS sales show "TEST MODE TRANSACTION" | store is in test mode | POS → header "Test mode" → confirm *Disable test mode* |
| "Too many failed sign-in attempts" in the POS | 5 wrong passwords in 15 min | wait 15 min, or Super Admin → Users → temporary password |
| "Your … plan allows up to N …" | plan limit | upgrade the plan or add a limit exception (Business → Exceptions) |
| Import says the plan allows N products | import is all-or-nothing | raise the limit or split the file |
| Session keeps signing out | site opened over http:// or mixed hosts | enable Force HTTPS Redirect; use https:// only |
| Suspended business still works for a few seconds | OPcache caches the registry | set `opcache.revalidate_freq` ≤ 2 |
| Sales sync alert "sync.failed" | business DB unreachable / wrong stored password | Business → Health; alert clears automatically after the next successful sync |

