[Bug][Prod][Calendar] GET events threw for every pre-#781 event — required non-nullable AffectsAvailability missing from old documents (backfilled)
#786
Reported via Seq by spikerj 2026-07-22: every GET api/Calendar/events failed with Document element is missing for required non-nullable property 'AffectsAvailability' — the #431 EF-Mongo landmine class, scalar edition. The #781 recurrence work added bool AffectsAvailability = false to CalendarEvent; the CLR default (and its 'Optional/backward-compatible' comment) doesn't help — the Mongo EF provider throws on READ when the element is absent from a stored document, so all 6 pre-existing events broke the whole range query.
RESOLVED by data backfill (2026-07-22 ~03:5xZ): updateMany({AffectsAvailability:{$exists:false}}, {$set:{AffectsAvailability:false}}) → matched=6 modified=6, 0 still missing, no recurrence of the error in logs since. Closing as fixed; reopen if the calendar still errors.
LESSON (2nd incident of this class — after #431's owned-nav variant): adding ANY required non-nullable member to a Mongo-mapped entity requires a same-PR backfill (or a nullable property with coalescing). Worth a rule-file note or a model test that flags new required scalars on existing collections.
Reported via Seq by spikerj 2026-07-22: every GET api/Calendar/events failed with `Document element is missing for required non-nullable property 'AffectsAvailability'` — the #431 EF-Mongo landmine class, scalar edition. The #781 recurrence work added `bool AffectsAvailability = false` to CalendarEvent; the CLR default (and its 'Optional/backward-compatible' comment) doesn't help — the Mongo EF provider throws on READ when the element is absent from a stored document, so all 6 pre-existing events broke the whole range query.
RESOLVED by data backfill (2026-07-22 ~03:5xZ): `updateMany({AffectsAvailability:{$exists:false}}, {$set:{AffectsAvailability:false}})` → matched=6 modified=6, 0 still missing, no recurrence of the error in logs since. Closing as fixed; reopen if the calendar still errors.
LESSON (2nd incident of this class — after #431's owned-nav variant): adding ANY required non-nullable member to a Mongo-mapped entity requires a same-PR backfill (or a nullable property with coalescing). Worth a rule-file note or a model test that flags new required scalars on existing collections.
CORRECTION + verified fix (2026-07-22 ~04:57Z): my first backfill wrote the C# property name 'AffectsAvailability' but the entity maps [BsonElement("affectsAvailability")] — so the provider kept throwing (spikerj's Chrome reloads kept 500ing while toddcan, with no pre-#781 events in range, loaded fine). Re-ran the backfill against the CORRECT camelCase element (6/6 set, bogus PascalCase keys removed, 0 missing) and Seq confirms: last error 04:53:58Z, zero since. Lesson doubled: backfills must target the MAPPED BsonElement name, verified against a real document's keys — not the C# property.
CORRECTION + verified fix (2026-07-22 ~04:57Z): my first backfill wrote the C# property name 'AffectsAvailability' but the entity maps [BsonElement("affectsAvailability")] — so the provider kept throwing (spikerj's Chrome reloads kept 500ing while toddcan, with no pre-#781 events in range, loaded fine). Re-ran the backfill against the CORRECT camelCase element (6/6 set, bogus PascalCase keys removed, 0 missing) and Seq confirms: last error 04:53:58Z, zero since. Lesson doubled: backfills must target the MAPPED BsonElement name, verified against a real document's keys — not the C# property.
Closing — this is the plainest case of the habit this audit is chasing: the body itself ends "Closing as fixed; reopen if the calendar still errors," and the state was never flipped. Seven days open on a ticket its own author declared resolved.
Verified before closing:
The backfill is recorded as complete (2026-07-22 ~03:5xZ): updateMany({AffectsAvailability:{$exists:false}}, {$set:{AffectsAvailability:false}}) → matched=6, modified=6, 0 still missing, no recurrence in logs.
SpikerSoft.Data/Mongos/CalendarEvent.cs:159 — public bool AffectsAvailability { get; set; } = false; with the backward-compatibility comment at :154. The property is as the ticket describes; the data is what was repaired, which is correct for this failure mode.
On the LESSON item — the body suggests "worth a rule-file note or a model test that flags new required scalars on existing collections." That's phrased as a suggestion rather than acceptance criteria, so I'm not holding the ticket open for it. Worth recording that it did partly propagate on its own: SpikerSoft.Data/Mongos/ArtStudio/ArtAsset.cs:85 and ArtAssetGenerationParams.cs:36 both now carry explicit doc comments warning about "Document element is missing for required non-nullable property", and #843's ArtAssetGenerationParams was deliberately built with every scalar nullable for exactly this reason — with ArtAssetLegacyDocumentTests.cs:430-453 pinning it behaviourally.
So the knowledge reached the next engineer who needed it, via code comments rather than a rule file. If you still want the systematic guard — a test that flags any new required scalar on an existing Mongo-mapped collection — that's worth its own ticket, since it would cover the whole model surface rather than this one incident. This is now the third occurrence of the class (#431 owned-nav variant, this one, and the near-miss #843 avoided).
Closing.
Closing — this is the plainest case of the habit this audit is chasing: **the body itself ends "Closing as fixed; reopen if the calendar still errors," and the state was never flipped.** Seven days open on a ticket its own author declared resolved.
Verified before closing:
- The backfill is recorded as complete (2026-07-22 ~03:5xZ): `updateMany({AffectsAvailability:{$exists:false}}, {$set:{AffectsAvailability:false}})` → matched=6, modified=6, 0 still missing, no recurrence in logs.
- `SpikerSoft.Data/Mongos/CalendarEvent.cs:159` — `public bool AffectsAvailability { get; set; } = false;` with the backward-compatibility comment at `:154`. The property is as the ticket describes; the data is what was repaired, which is correct for this failure mode.
**On the LESSON item** — the body suggests "worth a rule-file note or a model test that flags new required scalars on existing collections." That's phrased as a suggestion rather than acceptance criteria, so I'm not holding the ticket open for it. Worth recording that it *did* partly propagate on its own: `SpikerSoft.Data/Mongos/ArtStudio/ArtAsset.cs:85` and `ArtAssetGenerationParams.cs:36` both now carry explicit doc comments warning about `"Document element is missing for required non-nullable property"`, and #843's `ArtAssetGenerationParams` was deliberately built with every scalar nullable for exactly this reason — with `ArtAssetLegacyDocumentTests.cs:430-453` pinning it behaviourally.
So the knowledge reached the next engineer who needed it, via code comments rather than a rule file. If you still want the systematic guard — a test that flags any new required scalar on an existing Mongo-mapped collection — that's worth its own ticket, since it would cover the whole model surface rather than this one incident. This is now the **third** occurrence of the class (#431 owned-nav variant, this one, and the near-miss #843 avoided).
Closing.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Reported via Seq by spikerj 2026-07-22: every GET api/Calendar/events failed with
Document element is missing for required non-nullable property 'AffectsAvailability'— the #431 EF-Mongo landmine class, scalar edition. The #781 recurrence work addedbool AffectsAvailability = falseto CalendarEvent; the CLR default (and its 'Optional/backward-compatible' comment) doesn't help — the Mongo EF provider throws on READ when the element is absent from a stored document, so all 6 pre-existing events broke the whole range query.RESOLVED by data backfill (2026-07-22 ~03:5xZ):
updateMany({AffectsAvailability:{$exists:false}}, {$set:{AffectsAvailability:false}})→ matched=6 modified=6, 0 still missing, no recurrence of the error in logs since. Closing as fixed; reopen if the calendar still errors.LESSON (2nd incident of this class — after #431's owned-nav variant): adding ANY required non-nullable member to a Mongo-mapped entity requires a same-PR backfill (or a nullable property with coalescing). Worth a rule-file note or a model test that flags new required scalars on existing collections.
CORRECTION + verified fix (2026-07-22 ~04:57Z): my first backfill wrote the C# property name 'AffectsAvailability' but the entity maps [BsonElement("affectsAvailability")] — so the provider kept throwing (spikerj's Chrome reloads kept 500ing while toddcan, with no pre-#781 events in range, loaded fine). Re-ran the backfill against the CORRECT camelCase element (6/6 set, bogus PascalCase keys removed, 0 missing) and Seq confirms: last error 04:53:58Z, zero since. Lesson doubled: backfills must target the MAPPED BsonElement name, verified against a real document's keys — not the C# property.
Closing — this is the plainest case of the habit this audit is chasing: the body itself ends "Closing as fixed; reopen if the calendar still errors," and the state was never flipped. Seven days open on a ticket its own author declared resolved.
Verified before closing:
updateMany({AffectsAvailability:{$exists:false}}, {$set:{AffectsAvailability:false}})→ matched=6, modified=6, 0 still missing, no recurrence in logs.SpikerSoft.Data/Mongos/CalendarEvent.cs:159—public bool AffectsAvailability { get; set; } = false;with the backward-compatibility comment at:154. The property is as the ticket describes; the data is what was repaired, which is correct for this failure mode.On the LESSON item — the body suggests "worth a rule-file note or a model test that flags new required scalars on existing collections." That's phrased as a suggestion rather than acceptance criteria, so I'm not holding the ticket open for it. Worth recording that it did partly propagate on its own:
SpikerSoft.Data/Mongos/ArtStudio/ArtAsset.cs:85andArtAssetGenerationParams.cs:36both now carry explicit doc comments warning about"Document element is missing for required non-nullable property", and #843'sArtAssetGenerationParamswas deliberately built with every scalar nullable for exactly this reason — withArtAssetLegacyDocumentTests.cs:430-453pinning it behaviourally.So the knowledge reached the next engineer who needed it, via code comments rather than a rule file. If you still want the systematic guard — a test that flags any new required scalar on an existing Mongo-mapped collection — that's worth its own ticket, since it would cover the whole model surface rather than this one incident. This is now the third occurrence of the class (#431 owned-nav variant, this one, and the near-miss #843 avoided).
Closing.