Eleven October counts, 2014 to 2024 · on two different counted populations
Once a year New Jersey publishes, for every district, how many students it enrolled and how many of them held an individualized education program. The share is called the classification rate. It is one of the most useful numbers a parent can have about a district, and one of the easiest to read as something it is not. This page is the manual for both halves of that.
The federal Individuals with Disabilities Education Act requires every state to report, under Section 618, a count of the children it serves in special education. New Jersey publishes its answer as a single spreadsheet on the Office of Special Education's public IDEA data page, with two worksheets:
| Worksheet | What it holds | Rows |
|---|---|---|
| District Rates | One row per NJDOE district reporting unit: total enrollment, the count of students with an IEP, and the classification rate NJDOE calculated from them. | 655 districts |
| State Rates | The statewide total, plus one row for each of 13 disability categories — count of students and a statewide rate. No district appears here. | 14 rows |
Everything is measured on a single day: October 15, 2024. There is no earlier and no later figure in this file, so nothing on our pages built from it is a trend, and no movement can be read from it.
Statewide, NJDOE counted 1,394,970 students and 242,001 with an IEP — a classification rate of 17.35%. District rates run from 0.0% to 65.57%.
This is the most important fact on the page, and it is invisible in the numbers themselves.
Through the October 2018 count, NJDOE's classification file counted public and non-public students together — New Jersey districts are responsible for classifying and serving students who attend private schools within their borders, and those children were in both the numerator and the denominator. From the October 2019 count onward, the file counts public school students only.
Nobody announced it in the workbook. There is no note, no changed title, no flag. The column headers barely move. If you line the eleven years up and read them as one series, you will see a drop between 2018 and 2019 that looks like New Jersey classifying fewer children — and it is nothing of the kind.
So the district pages draw two lines and never join them. The public-only series is the trend, because that is what NJDOE publishes now; it can only begin in 2019, because no public-only figure exists for any earlier year — the older counts cannot be converted. The combined-basis years are drawn separately, dashed and muted, on their own basis, with a marked break between them. In the two overlap Octobers both marks appear in the same column, so the distance between them is the size of the change, on that district's own numbers.
Years on one side of the break can be compared with each other. Across it there is no fair comparison, and we draw none.
A classification rate counts the students who held an IEP on one October day. It has no direction. There is no “good” value.
This is the part that matters most, so it is worth being blunt about. A district whose rate sits above New Jersey's 17.35% may be finding and identifying students that other districts miss — or it may be classifying children who would not be classified a town over. A district below it may be under-identifying students who need help — or it may serve a population with less need. Nothing in this file distinguishes those cases, and neither can we.
| The rate is… | The rate is not… |
|---|---|
| An administrative count of who held an IEP on 15 October 2024 | A count of how many students need special education |
| The publisher's own arithmetic, reproduced not recomputed | A measure of whether the services those students get are any good |
| Comparable across districts as a count | Comparable across districts as a judgment — a higher number is not better or worse |
| One day's record | Evidence about staffing, spending, out-of-district tuition, placement, program appropriateness, or compliance with anything |
The four highest rates in the state belong to entities that are not ordinary school districts: the Department of Corrections education office (65.57%), the Department of Children and Families education office (40.55%), the Juvenile Justice Commission (39.6%), and Seaside Heights (41.88%). Placement settings enroll students who were sent to them because they need services, so a rate three times the state's says something about what kind of entity it is, not about how it serves a neighborhood.
650 of 655 districts publish cleanly. The five that do not are the interesting ones, and they are empty in three different ways that must never be collapsed into a zero:
| Code | District | Enrollment | Students with IEP | Rate |
|---|---|---|---|---|
2220 | Holland Township | 522 | empty cell | empty cell |
8505 | Bergen Co JDC | * withheld | 0 | 0% |
8509 | Essex Co JDC | 5 | 0 | 0% |
8511 | Middlesex Co JDC | * withheld | 0 | 0% |
8513 | Ocean Co JDC | * withheld | 0 | 0% |
Three states, three different acts by the publisher:
*) — NJDOE holds the figure and did not release it, at three county juvenile detention centers whose enrollment is small enough that publishing it could identify individuals. The state knows the number. You do not.On the district pages a withheld cell keeps NJDOE's own * so the mark is the publisher's and not ours, an empty cell reads “Not published,” and a printed zero is shown as the figure it is. Holland Township never shows a 0.
Three questions follow immediately from a classification rate, and this workbook answers none of them at the district level. But NJDOE does answer them, in other files it publishes alongside this one, and until 1 August 2026 our district pages wrongly said otherwise:
| Question | What this workbook has | Where NJDOE actually publishes it |
|---|---|---|
| Which disabilities? | 13 categories for New Jersey as a whole, and only in four of the eleven editions. No district breakdown. | Special Education Student Count — by district, in all eleven editions, broken out by disability, race, gender and English-language status. |
| How does it break down by race? | Nothing, at any level. | The same three sibling report families, all by district, all eleven editions. |
| Are these students in general-education classrooms? | Nothing, at any level. | Education Environment (Placement) — by district, in all eleven editions. Exiting Special Education covers how students leave. |
The statewide breakdown that does exist, for context: specific learning disability is the largest category at 67,445 students, then speech or language impairment (52,985), other health impairment (46,874) and autism (31,715). The smallest is deaf-blindness — 18 students, whose published rate is exactly 0, because a rate carried to four decimal places as a fraction rounds 18 out of 1.39 million to nothing. That zero is a rounding artifact, not a count, and it cannot honestly be printed without the 18. We do not currently render the category breakdown at all; it is not part of the data we load.
The workbook is a 2025-edition file. Its embedded document title says “School Year 2023-24.” The reference date NJDOE states for the data inside it is October 15, 2024, which falls in 2024-25.
All three labels are in the same artifact and they do not agree. We preserve the conflict rather than picking a winner: the reference date is what we print as the period, and wherever it appears we say that the embedded title disagrees. Neither label is ever printed alone.
We join this file to our districts on the exact zero-padded NJDOE district code, and never on names. Of the 587 district reports our build writes, 558 match; the other 29 have no row in the source and show nothing rather than a guess.
That omission has an awkward shape worth naming: 20 of the 29 are the county special-services districts, educational-services commissions and jointure commissions — which is precisely the population a reader arriving at a special-education page most wants to look up. A name-based fallback would fill those pages by attaching some neighboring district's rate to an entity that never reported one, and that is a worse answer than an absence. The remaining nine are ordinary districts (codes 0130, 0200, 0810, 2120, 2160, 3145, 4700, 4720 and 5490) with no source row.
The workbook arrives as an exact, verified offline pin from our upstream data warehouse; this repository downloads and parses nothing. The build checks the whole artifact — 670 source rows, 1,994 typed values, three metric definitions and every value-state population — before writing anything, then projects the district all-iep-students rows and the statewide total into two tables:
| Table | Holds | Rows |
|---|---|---|
idea_classification_district | District identity, the reference date, and for each of enrollment, students with an IEP and the classification rate: the value, the publisher's exact literal, its value state, and the workbook cell it came from | 655 |
idea_classification_state | The statewide comparator, including the rate in the publisher's native fraction scale as well as percentage points | 1 |
Every cell keeps its own value state — that field is what separates a withheld figure from an empty one from a printed zero, and without it all three are the same blank spreadsheet cell. The statewide disability categories are deliberately not projected: nothing on the site renders them, so nothing on the site can render them wrongly.
The data appears in two places: the How many students have an IEP section on each district profile, and the Costs and students section of each district budget report, where it sits beside the later budget-planning row precisely so a reader can see that the two are different quantities.
Source data: New Jersey Department of Education, Office of Special Education, 2025 IDEA Section 618 Public Reporting — Classification Rates (nj.gov/education/specialed/monitor/ideapublicdata), reference date October 15, 2024.
Every dataset behind this site keeps a structured registry of its known issues — the format breaks, suppression rules, entry errors, and definitional traps we hit while building on it — so that the next person (or agent) who works with this data doesn't rediscover them the hard way. Each issue has a stable id, a machine-readable scope (which years, columns, and tables it touches), and an effect: breaks stops a pipeline, corrupts silently wrongs the numbers, misleads invites a wrong reading of right numbers, context is background you must hold to use the data responsibly. Issues marked ★ are core: read them before any use of this data. The registry is maintained in the ergo format and served in machine-readable form alongside this page — links at the end of this section.
NJ Department of Education, Office of Special Education · source confidence A · updated 2026-08-03 · 10 known issues (3 core)
The pitfall: NJDOE counted public and non-public students through October 2018 and public-school students only from October 2019 — a 1.13 to 1.21 percentage-point step statewide — so no figure may be joined, averaged or compared across that break.
Type: suppression — applies to tables: idea_classification_district · columns: total_enrollment_state, students_with_iep_state, classification_rate_state · rows: total_enrollment_state <> 'reported' OR students_with_iep_state <> 'reported'
How to spot it: Value-state populations in idea_classification_district: total_enrollment 652 reported / 3 suppressed; students_with_iep and classification_rate 650 reported / 4 exact-reconciliation-zero / 1 not-collected. The suppressed literal is `*` and the not-collected literal is the empty string. No classification rate is suppressed anywhere in the file — suppression lands only on the denominator.
The misread: Rendering `*` or the empty literal as 0 or 0%. Holland Township (2220) reports 522 students and no IEP count at all; printed as a zero it becomes a district where no child has an IEP. Conversely, greying the four printed zeros as 'not available' deletes a figure NJDOE published.
Full entry, with the story and the numbers, in the served ergo doc.
Type: definitional — applies to tables: idea_classification_district, idea_classification_state · columns: classification_rate_value
How to spot it: The published district rates run from 0.0 to 65.57 percentage points against a statewide 17.35. The four highest are state-operated or county-operated programs — Department of Corrections education (65.57), Department of Children and Families education (40.55), the Juvenile Justice Commission (39.6) — placement settings whose enrolled population arrives already classified. Nothing in the file distinguishes a district that identifies students well from one that over-identifies them, and there is no direction in which the number is better.
The misread: Reading a high rate as unmet need being met, or as over-classification; reading a low rate as under-identification, or as a healthy population. Ranking districts on the rate. Placing the rate beside the UFB special-education planning share as if the difference between them meant something — different population, different date, different file.
Full entry, with the story and the numbers, in the served ergo doc.
Type: coverage — applies to tables: idea_classification_district_history, idea_618_report_family · columns: category_id, coverage_state, levels, breakdowns · entities: all district reporting units, all eleven editions
How to spot it: In the classification-rate release every district-level cell is `all-iep-students`; the 13 `idea-disability-*` categories appear only in statewide rows, and only in the four editions that ship the category workbook. In the sibling release `nj-idea-618-report-families`, `coverage_cell` shows `student-count`, `education-environment` and `exiting` as `held-tabular` at `district` level in all 11 editions, each with breakdowns `disability`, `gender`, `lep` and `race`. `_validate_projection` fails the build if any of the three stops holding eleven district-grain tabular editions.
The misread: Telling a reader that a district disability, race or placement breakdown does not exist. It does — NJDOE publishes it, at district grain, in every edition; this repo simply has not loaded the values yet. The unscoped absence claim shipped on district profiles until 2026-08-01 and sent readers away from data the state publishes, which is the same error the accountability band made. Also wrong in the other direction: reading the statewide category shares as this district's.
Full entry, with the story and the numbers, in the served ergo doc.
Type: universe — applies to tables: idea_classification_edition, idea_classification_district_history, idea_classification_state_history, idea_classification_category_history · columns: coverage_universe · rows: all
How to spot it: `coverage_universe` on every source row and measure value. Editions 2015-2019 (reference dates 2014-10-15 to 2018-10-15) carry `public-and-nonpublic` only; editions 2020-2022 (2019-10-15 to 2021-10-15) carry `public-only` only; editions 2023 and 2024 (2022-10-15, 2023-10-15) carry BOTH; edition 2025 (2024-10-15) carries `public-only`. Measured on the two overlap years: statewide the rate differs by 1.13pp (17.63 vs 16.51, 247,313 vs 228,241 students) and 1.21pp (18.35 vs 17.14, 259,375 vs 238,721). At district grain only 455 of 648 and 464 of 653 districts have identical rates; among the rest the median move is 0.92pp and 0.95pp and the maximum is 43.85pp and 44.94pp. `EXPECTED_SEAM_STRENGTH` pins all five statistics per year and the build fails on drift.
The misread: Joining the two bases with one line, averaging across them, computing a change from a pre-2019 year to a post-2019 one, or ranking a district's oldest rate against its newest. District 2520 reads 78.35% on the combined basis and 33.41% on the public-only basis in the SAME October — a reader shown one line through that has been told a district halved its classification rate when nothing about it changed.
Full entry, with the story and the numbers, in the served ergo doc.
Type: coding — applies to tables: idea_classification_edition, idea_classification_district_history · columns: denominator_label, denominator_names_general_education, total_enrollment_value · entities: editions 2015, 2016, 2017, 2018, 2019, 2021 and 2022
How to spot it: `idea_classification_edition.denominator_label` per edition: `Gened` (2015, 2016), `General Ed. Enrollment` (2017, 2018, 2019, 2021, 2022), `Total Enrollment` (2020, 2025), `All Students Count` (2024), and two different misspellings in 2023 — `Genral Education Enrollment count` and `General Education Enrollement Count`, one per coverage universe. `denominator_names_general_education` flags the seven; `EXPECTED_DENOMINATOR_LABELS` and `EXPECTED_MISLABELLED_DENOMINATOR_EDITIONS` pin them and the build fails on drift.
The misread: 'Fixing' the rate by adding the IEP count back onto the denominator, on the theory that a general-education enrollment excludes classified students. It does not — the header is wrong, not the figure — and the correction deflates every rate in the seven affected editions. Recomputing the rate from the two counts at all: the site prints NJDOE's published rate and does not recompute it.
Full entry, with the story and the numbers, in the served ergo doc.
Type: identity — applies to tables: idea_classification_edition, idea_classification_district_history · columns: identity_match_state, match_rate_percent · rows: reference_date < '2020-08-11'
How to spot it: `idea_classification_edition.match_rate_percent` ranges 97.546 to 99.542 across the thirteen edition-universe registers; `identity_evidence_floor` is 2020-08-11 on every row. `EXPECTED_IDENTITY_MATCH_RANGE` pins the range.
The misread: Reading a 2014 row and a 2024 row on one district page as two observations of the same district without qualification. New Jersey has merged, split and regionalised districts across this span, and this dataset cannot distinguish a stable district from a code reused after a reorganisation.
Full entry, with the story and the numbers, in the served ergo doc.
Type: coverage — applies to tables: idea_classification_category_history · columns: category_id, reported_label · entities: editions 2015-data, 2023-data, 2024-data, 2025-data
How to spot it: `idea_classification_category_history` holds 84 rows across editions 2015-data, 2023-data, 2024-data and 2025-data only; `EXPECTED_CATEGORY_EDITIONS` pins that set. Renames, detected after normalising case and dash characters: `Hearing impairment` to `Auditory Impairment`; `Emotional disturbance` to `Emotional Regulation Impairment`; `Preschool Disabled` to `Developmental Delay` to `Preschool Child with a Disability`. `EXPECTED_CATEGORY_RENAMES` pins all three. `Deaf-blindness` versus `Deaf–blindness` is an en dash, not a rename, and is deliberately excluded.
The misread: Drawing an eleven-point line for a disability category, or treating a category's disappearance between 2015 and 2023 as a change in prevalence when it is a change in the file format. Also: reporting the en-dash respelling as a renamed category, which buries the three that genuinely moved.
Full entry, with the story and the numbers, in the served ergo doc.
Type: measurement — applies to rows: category_id = 'idea-disability-deaf-blindness' AND metric_id = 'idea.classification.rate-percent' · entities: statewide Deaf-Blindness disability category
How to spot it: In the pinned release, category `idea-disability-deaf-blindness` carries students-with-IEP literal `18` typed reported, and rate literal `0` typed exact-reconciliation-zero, at `State Rates!8:B` and `State Rates!8:C`. Every other statewide category publishes a non-zero fraction; the three next-smallest (visual impairment, traumatic brain injury, orthopedic impairment) publish `0.0002`.
The misread: Printing the category's rate as 0 or 0% without its headcount, which says no New Jersey student is deaf-blind. The zero is a rounding artifact of a rate expressed as a fraction to four decimal places, not a count.
Full entry, with the story and the numbers, in the served ergo doc.
Type: entry — applies to the whole dataset
How to spot it: Release metadata carries `publisher_edition = 2025`, `reference_date = 2024-10-15` and `embedded_title_defect = School Year 2023-24`. The conflict is inside the published file and is preserved rather than reconciled.
The misread: Labeling the figures `2023-24` from the embedded title, or `2025` from the edition. Either label alone attaches the count to a school year NJDOE did not say it measures.
Full entry, with the story and the numbers, in the served ergo doc.
Type: linkage — applies to tables: idea_classification_district · columns: district_code · entities: 29 rendered districts with no exact-code source row
How to spot it: 558 of 587 rendered district budget reports match by exact zero-padded NJDOE district code; the 29 that do not are locked in tests/test_aquifer_idea_classification_adapter.py. Twenty carry special-services, educational-services-commission or jointure-commission routes; the other nine are ordinary districts (0130, 0200, 0810, 2120, 2160, 3145, 4700, 4720, 5490) with no source row.
The misread: Falling back to a name match to fill the gap, which would attach a neighboring district's classification rate to a special-services entity. Reading the absence as a district with no students holding IEPs.
Full entry, with the story and the numbers, in the served ergo doc.
Machine-readable: this page as an ergo doc · all datasets (index.json) · format: ergo · implementation: source repo
The text on this page was generated by Claude Opus 5, working as part of a stack of tools created by Lyra Forge.