Skip to main content
Schoolyi
School librarian arranging books and planning cards in a bright library

Browse docs

Getting started

Admissions troubleshooting

Why the Admissions menu is missing for leadership, what each enrolment refusal code means, and why offers never expire on their own.

Getting started guide for day and boarding schools.

Last updated August 29, 2026

Admissions is the one module where access does not follow the role. Membership of the Admissions committee is what opens the staff screens, and chairing that committee - or holding the Principal or Vice Principal role - is what allows cycles, tests, shortlists, offers, and enrolment to be changed. Platform Admin is the only role that bypasses both checks. Before treating anything on this page as a data problem, confirm the person is on the committee at /committees.

Permission problem or configuration problem?

A permission problem here hides whole navigation entries rather than producing an error, which is why it is so often misread as a broken deployment. If somebody cannot see Admissions in the sidebar at all, that is committee membership every time. If they can see the screens but a specific action refuses, read the code in the response: it names the record that has to change. There is one asymmetry worth knowing when you are testing through the API rather than the interface - a Principal who is not on the committee is treated as in charge by the enrolment and cycle endpoints even though the staff interface stays hidden from them, so an API call can succeed for somebody who cannot reach the button.

Enrolment refusals

SymptomCauseFix
Offer status must be ACCEPTEDThe guardian has not accepted, or staff accepted on the wrong recordAccept from the offer link or at /admissions/offers. Acceptance also moves the application to OFFER_ACCEPTED, and enrolment checks both.
NO_SEATS_AVAILABLENo active class section for that grade and stream has a free seatRaise the capacity on the section at /classes or create another section for the grade. The message repeats the grade and stream it searched for.
ENROLLMENT_STATE_MISMATCH with 409The application says enrolled but no student record existsA previous run failed part-way. This one needs support: the recovery path is separate and the retry will keep refusing.
Second enrolment attempt appears to do nothingIt is idempotentWhen the application is already enrolled and the student exists, the endpoint returns 200 with the existing record rather than creating a duplicate.

Offers, tracking, and email

SymptomCauseFix
Guardian cannot open the offer acceptance formIdentity proof does not matchThe guardian must supply the parent email and the student date of birth exactly as recorded on the application before the offer is shown.
"Offer has expired" although nothing expired itThe deadline is enforced at accept timeAcceptance compares the current time to acceptanceDeadline regardless of whether the expiry job has ever run. Reissue the offer with a later deadline.
Applicant cannot track their applicationWrong registration number or date of birthTracking at /admissions/track matches both fields exactly as submitted on the form.
Offer letter email never arrivedSMTPThe notification row records emailStatus SENT or FAILED, so the application detail shows the attempt even when delivery failed. Test outbound mail at /settings/email-test.
Enrolled student has an odd email addressNo student email on the applicationEnrolment generates a synthetic address ending in @students.local from the registration number. Receipts and result notices sent to the student will go nowhere until it is replaced.

Common questions

Quick answers in plain language.

A Principal cannot see the Admissions section at all. Is that a bug?+

It is the access rule. Only Platform Admin reaches the admissions staff screens on role alone. Everyone else, Principal and Vice Principal included, must also be a member of a committee whose name, code, or type identifies it as the Admissions committee. Add them to the committee at /committees and the section appears.

Enrolment fails with DOCUMENTS_NOT_VERIFIED. Which documents does it mean?+

The check looks at the required document types for the application and refuses while any of them is present but unverified. The error lists the labels by name, so open the application at /admissions/applications, tick each document as verified on the detail screen, and retry. Nothing else in the pipeline enforces this, so an offer can be accepted with unverified paperwork and only stop at enrolment.

Why is enrolment refused with STUDENT_ALREADY_EXISTS for a family that has never enrolled?+

The duplicate guard looks for an active student with the same first name, last name, and an active class membership, linked either by the parent email on the application or by a guardian record carrying it. Twins or siblings with the same given name and the same parent email will trip it. Check the student id returned in the response before assuming the guard is wrong.

Do admission offers expire by themselves once the acceptance deadline passes?+

No. Expiry runs only when POST /api/admissions/cron/expire-offers is called, which scripts/run-school-cron.sh does when ADMISSIONS_CRON_SECRET is set. Waitlist promotion after an expiry additionally requires ADMISSIONS_AUTO_PROMOTE_WAITLIST=true. With neither in place, offers sit at pending indefinitely and the seat is never released, although a guardian trying to accept late is still refused with "Offer has expired".

Related searches

School leaders and IT teams often search for: how to module troubleshooting admissions in school management software, best school software onboarding for K-12 schools, Schoolyi module troubleshooting admissions guide, school ERP go live checklist, migrate from Excel to school ERP, and school software training guide.