[Bug][Backend][Quiz] GET /api/Quiz 500s — Quiz.DegradedPageNumbers (#559) & UnvalidatedQuestionDropCount (#564) are required non-nullable, so pre-deploy quizzes fail to materialize #606

Closed
opened 2026-07-16 01:37:13 +00:00 by spikerj · 1 comment
Owner

Symptom

GET /api/Quiz (GetAllQuizzesQuery) returns 500 in production:

System.InvalidOperationException: Document element is missing for required non-nullable property 'DegradedPageNumbers'.

A single legacy quiz document poisons the whole paginated list query — any caller whose collection contains one pre-#559 quiz gets a 500.

Root cause

SpikerSoft.Data/Mongos/Quiz.cs added two properties AFTER the original schema (2025-11-14):

Both are non-nullable, so the MongoDB EF Core provider's compiled shaper treats them as REQUIRED and throws when a BSON document written before those deploys lacks the element. Same class of outage as the ArtStudio #369 schema-evolution rule. Any quiz missing DegradedPageNumbers also predates #564, so fixing only the reported field would just move the 500 onto UnvalidatedQuestionDropCount.

Fix

Per the #369 rule: declare both post-original properties nullable and normalize absence in the accessors (empty list / 0) so old documents materialize and new writes keep populating them (next save heals the document). Add a FakeMongoClientWrapper legacy-document regression test (real shaper) plus a schema-evolution guard asserting only original-era Quiz fields may be required. No data backfill required, though a one-time $set on old quizzes would also resolve it.

## Symptom GET /api/Quiz (GetAllQuizzesQuery) returns 500 in production: ``` System.InvalidOperationException: Document element is missing for required non-nullable property 'DegradedPageNumbers'. ``` A single legacy quiz document poisons the whole paginated list query — any caller whose collection contains one pre-#559 quiz gets a 500. ## Root cause `SpikerSoft.Data/Mongos/Quiz.cs` added two properties AFTER the original schema (2025-11-14): - `DegradedPageNumbers` (`List<int>`) in #559 - `UnvalidatedQuestionDropCount` (`int`) in #564 Both are non-nullable, so the MongoDB EF Core provider's compiled shaper treats them as REQUIRED and throws when a BSON document written before those deploys lacks the element. Same class of outage as the ArtStudio #369 schema-evolution rule. Any quiz missing `DegradedPageNumbers` also predates #564, so fixing only the reported field would just move the 500 onto `UnvalidatedQuestionDropCount`. ## Fix Per the #369 rule: declare both post-original properties nullable and normalize absence in the accessors (empty list / 0) so old documents materialize and new writes keep populating them (next save heals the document). Add a FakeMongoClientWrapper legacy-document regression test (real shaper) plus a schema-evolution guard asserting only original-era Quiz fields may be required. No data backfill required, though a one-time `$set` on old quizzes would also resolve it.
Author
Owner

Resolved in spikersoft-backend PR #311 (merged to master). Quiz.DegradedPageNumbers (#559) and Quiz.UnvalidatedQuestionDropCount (#564) were non-nullable properties added after the schema existed, so the EF-Mongo shaper threw Document element is missing for required non-nullable property on legacy quizzes, 500-ing GET /api/Quiz. Made both nullable with normalizing accessors per the #369 schema-evolution rule; added 4 legacy-document tests via the real shaper. Deployed + verified (no deser errors in API logs; endpoint healthy). The QuizGeneration worker shares the same Quiz.cs fix and picks it up on its next image deploy. Closing.

Resolved in spikersoft-backend PR #311 (merged to `master`). `Quiz.DegradedPageNumbers` (#559) and `Quiz.UnvalidatedQuestionDropCount` (#564) were non-nullable properties added after the schema existed, so the EF-Mongo shaper threw `Document element is missing for required non-nullable property` on legacy quizzes, 500-ing `GET /api/Quiz`. Made both nullable with normalizing accessors per the #369 schema-evolution rule; added 4 legacy-document tests via the real shaper. Deployed + verified (no deser errors in API logs; endpoint healthy). The QuizGeneration worker shares the same `Quiz.cs` fix and picks it up on its next image deploy. Closing.
Sign in to join this conversation.