Troubleshooting
Common problems and fixes — configuration errors, login issues, and sync failures.
Common issues
| Symptom | Likely cause | Fix |
|---|---|---|
| "Failed to save" on Azure config | CONFIG_ENCRYPTION_KEY not set or not 64 hex chars | Generate a valid key: openssl rand -hex 32 and set it in Vercel env |
| Login email never arrives | No email transport configured | Set up Azure AD (with Mail.Send permission) or SMTP under Admin → Config |
| SMTP test fails | Wrong credentials or blocked port | Check host, port, username, password. Gmail requires an app-specific password |
| Empty user list / person selector | person_codes sync failed | Check ERP and Azure/Google connection config; look for errors in Admin → Cache |
| "Forbidden" when editing an ERP activity | Activity belongs to a different ERP connection than expected | Confirm the correct connection is configured and the user has access in Standard Books |
| Google "delegation denied" | Service account not authorized in Workspace Admin | Re-add the service account client ID under Security → API controls → Domain-wide Delegation |
| Google "insufficient permissions" | OAuth scopes are incomplete | Re-add all three scopes in Workspace Admin → Manage Domain-wide Delegation |
| Calendar shows no events after setup | Sync has not run yet, or connection is unhealthy | Go to Admin → Cache → Force sync, or check connection error messages |
| PWA shows empty on first install | Normal on first load — stubs restore from cache | Wait a moment for the API to load, or pull to refresh |
| Cron endpoint returns 401 | CRON_SECRET header missing or wrong | Check that CRON_SECRET is set in Vercel env and matches what the caller sends |
| Cron endpoint returns 500 | CRON_SECRET env var not set on the server at all | Add CRON_SECRET to Vercel → Project → Settings → Environment Variables |
| Duplicate members in Admin → Members | Same person has slightly different email/code across ERP and Azure | Use the Merge action in the duplicate candidates banner at the top of Admin → Members |
Checking connection health
Admin → Cache shows the sync status per connection — last run timestamp, next scheduled run, and any error message. A connection showing a red error badge needs attention before it will sync.
For ERP connections, the most common errors are credential expiry (rotate the OAuth token or basic-auth password in the ERP, then update the connection in Admin → Config) and unreachable API URLs (firewall change or ERP server moved).
Checking cron health
On Vercel, the Cron tab shows last-run status per scheduled route. A red entry means the route returned a non-200 status on its last run. Check Vercel runtime logs for the error body.
For manual investigation, run a job with scripts/herbe-cron.sh <job> dryrun from any host with the env vars configured. See Cron jobs for the full reference.