Appearance
Troubleshooting
Sign-in
| Symptom | Likely cause | What to try |
|---|---|---|
| Invalid credentials | Wrong password or tenant | Confirm subdomain (or use Find your school portal) and ask admin to re-invite |
| Cannot remember the portal URL | Forgot the school subdomain | Open schoolrota.com/login and enter the school name or the short name from the welcome email |
| No password reset email | SSO-only account or unknown email | Use school SSO, or ask an admin to confirm your login email |
| Reset link invalid or expired | Token older than one hour | Request a new link from Forgot password? |
| Reset works locally but not production | EMAIL_PROVIDER=console | Set EMAIL_PROVIDER=resend and RESEND_API_KEY in deployment |
| No Microsoft / Google button | SSO not activated | Use email/password; see SSO setup |
| Portal URL is one school, screen shows another | Still signed in to a previous school (path-mode cookies on localhost are shared across /t/{school}) | Use Sign in to this school, or open the school you are already signed in to. Production hostnames isolate sessions per school |
| Staff app says it is not enabled | Operator has not turned on Staff companion app | Ask SchoolRota support to enable staff_app for the school |
| Staff app Face ID fails after a new fingerprint | Device lock enrolment changed | Sign in with school SSO or password again, then turn Face ID back on |
SCIM provisioning
| Symptom | Likely cause | What to try |
|---|---|---|
| 401 from IdP test | Wrong or revoked token | Generate a new token in Admin → SCIM provisioning |
| 403 SCIM not enabled | Feature flag off | Enable scim in operator flags or generate a token (auto-enables on some setups) |
| User synced but cannot sign in | SCIM ≠ SSO | Send manual invite or wait for SSO activation |
| 409 duplicate user | Email already exists | Remove manual invite or deactivate old account |
| Groups not syncing | Not supported yet | Assign users directly in the IdP |
See SCIM provisioning.
Outlook calendar sync
| Symptom | Likely cause | What to try |
|---|---|---|
| Integration page missing | outlook_calendar flag off | New schools have it on. Operator can enable it in /operator |
| Health check fails | Entra permissions / UPN | Verify app registration, admin consent, mailbox scope |
| Sync job failed | Graph throttling or mailbox permission | Retry job in Admin; check Entra consent and the person Last error column |
| No events for staff | Person sync off or no email | Enable per-person sync; add email in staff directory |
See Outlook calendar.
Microsoft profile photos
| Symptom | Likely cause | What to try |
|---|---|---|
| Integration page missing | entra_profile_photos flag off | Operator can enable it in /operator. Missing flag counts as on |
| Health check fails | Entra User.Read.All or wrong tenant | Verify app registration, admin consent, and the health-check mailbox |
| Initials never change | No portal access or email mismatch | Invite or provision the person; match directory email to Entra UPN |
| One person missing | No Microsoft photo or Graph error | Check the Staff table last error; refresh photos after they add a photo in Microsoft 365 |
Google Calendar sync
| Symptom | Likely cause | What to try |
|---|---|---|
| Integration page missing | google_calendar flag off | Operator enables flag in /operator |
| Health check fails | Domain-wide delegation / scope | Verify client ID, Calendar scope, staff test email |
| Sync job failed | API error or mailbox permission | Retry job in Admin; check the person Last error column |
| No events for staff | Person sync off or no email | Enable per-person sync; publish the day first |
| Disconnect stuck | Cleanup jobs pending | Wait for cron; check recent sync jobs for errors |
See Google Calendar.
Setup and staff
| Symptom | Likely cause | What to try |
|---|---|---|
| No template slots | Day structure not saved | Add duty areas and a time window on the Day structure setup step |
| Same duty twice on the schedule | Suggested posts or import added the same area with a different code | Use Remove extra from all rotas on Day structure or Admin → Cover rules |
| Import preferences wrong | Missing column / fill colours | Use explicit Cover preference column in CSV |
| Person missing from assign list | Inactive / not imported / erased | Check Staff directory |
| Person on cover while on leave | Only day absence recorded | Use Long-term leave on Staff → Edit |
| Part-time staff over-assigned | No working pattern | Set working days & hours on staff record |
| Cannot erase staff member | Tenant owner or already erased | Transfer ownership first; erasure is one-way |
| Want the setup wizard from scratch | Loaded demo data, wrong rota, or a botched first pass | Press Start over at the top of Setup and choose a new staff list or rota. Before go-live, the owner can also type the school name to wipe this school's rota data. After go-live a full wipe is not available; add another school if you need a clean school |
| GDPR export empty or fails | Permissions or erased profile | Use admin account; export unavailable after erasure |
Today and cover
| Symptom | Likely cause | What to try |
|---|---|---|
| Empty board | Not built yet | Select Build day on Today or Timetable |
| Cannot publish | Missing rota.publish | Sign in as duty lead / admin |
| Persistent unfilled posts | Insufficient eligible staff | Adjust cover preference, headcounts, or accept only-if-needed cover |
| Amber clash tags | Teaching, weekly block, or same-time other-school overlap | Review manually. Teaching and weekly block clashes block publish only if Cover policy is set to block for that kind. Same-time duty at another school is At risk after a confirmed override and does not block publish |
| Publish blocked (teaching) | Cover policy = block and lesson clash on board | Fix assignments or set Admin → Cover policy to warn-only |
| Publish blocked (weekly block) | Cover policy = block and a PPA or similar block clash on board | Fix assignments or set Admin → Cover policy to warn-only |
| Publish blocked (class cover) | Cover policy = block and lessons still need cover | Assign cover, mark not required, or set Admin → Cover policy to warn-only |
| Board stale | SSE lag | Wait ~15s or reload |
Notifications
| Symptom | Likely cause | What to try |
|---|---|---|
| Empty inbox | No matching rule / no publish yet | Publish a day; check rule audience/channels |
| No email in local | EMAIL_PROVIDER=console | Read server console logs |
| Email delayed until morning | Quiet hours or digest enabled | Check Notifications → Automatic email settings |
| Same-day change not emailed | Email toggle off for that trigger | Enable “Same-day change” in email settings |
| Digest never arrives | Cron not scheduled | Schedule GET /api/cron/notification-digest. See Deployment |
| Scheduled rota email never arrives | Cron not scheduled, or board not published | Schedule GET /api/cron/rota-document-email. Confirm the day or week is published and the send time uses the school timezone |
| Staff say no email | Check Recent sends delivery log | Confirm recipient has user account + email |
Exports and rota email
| Symptom | Likely cause | What to try |
|---|---|---|
| Empty file | Day not materialised | Build the day/week first |
| PDF missing colours | Browser print settings | Enable background graphics |
| Email rota: zero recipients | No emails or empty board | Add staff emails; build board before On rota only |
| Email rota failed | Email provider misconfigured | Same as notification email - not console in production |
Teaching timetable / hosted CSV
| Symptom | Likely cause | What to try |
|---|---|---|
| CSV pull: all unmatched | Staff emails/names differ from import | Match Staff directory; check Last sync summary samples |
| CSV pull: zero rows | Empty CSV or wrong URL | Open URL in browser; verify columns |
| Looking for SIMS, Arbor, PowerSchool or iSAMS | Native MIS connectors are coming soon | Export a CSV from your MIS and import it, or host the file and use Sync now |
Operator impersonation
| Symptom | Likely cause | What to try |
|---|---|---|
| Cannot impersonate | Target is operator account | Impersonation blocked for platform operators |
| Session ended unexpectedly | Impersonation timeout | Start a new session from /operator |
| Tenant user sees banner | Expected | Read-only support session; user is notified |
Still stuck?
- Check the Admin → Change history tab for recent changes
- Developers: see Local setup and
docs/SYSTEM_PLAN.md

