You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Tooling: ComponentSerializerCoverageTest forward check only scans Components.h -> forgotten non-trivial subsystem-header component escapes the data-loss guard #545
ComponentSerializerCoverageTest.EveryDeclaredComponentIsHandledBySceneSerializer — the guard that is supposed to catch "you added a component and forgot to serialize it" (the #325-class silent-data-loss species) — builds its declared universe from the raw text of Components.h only. Components declared in subsystem headers (not Components.h) are outside its universe, so a forgotten non-trivial subsystem-header component escapes the check entirely.
Evidence
ComponentSerializerCoverageTest.cpp:83: headerSrc = ReadFile(componentsHeader) (a raw text read — #includes are not expanded); line :96 iterates the struct \w+Component regex over headerSrc only.
Many serialized components live outside Components.h: e.g. struct InventoryComponent in Gameplay/Inventory/InventoryComponents.h (hand-written serialize SceneSerializer.cpp:5282, deserialize :3090); likewise AbilityComponent, IKTargetComponent, QuestJournalComponent, NavMeshBoundsComponent, StreamingVolumeComponent, the AI components, etc.
The asymmetry: the sibling ComponentTupleCoverageTest (ComponentHeaderRoots(), ~16 headers) and the inverse half of this same test (componentHeaderRoots, ~line 187) both scan the full subsystem-header list. Only the forward check regressed to Components.h-only. (CLAUDE.md's "greps a fixed header list" describes the inverse check — the forward missing-serialization guard does not cover subsystem headers.)
Reproduction
Add a non-trivial component (e.g. struct FooComponent with a Ref<T> field) to any subsystem header (say AIComponents.h) and forget its hand-written SceneSerializer.cpp block. It is classified non-trivial (so not auto-generated), never hand-written, and not in declared (not in Components.h) → the forward test passes → silent scene-YAML data loss ships, undetected by the very guard meant to prevent it.
Fix direction
Repoint the forward check's declared set at the full header-root list the inverse check + ComponentTupleCoverageTest already use (ComponentHeaderRoots() / componentHeaderRoots), so the forward and inverse checks share one component universe. Trivial change; it closes a real hole in a data-loss safety net.
Activity
coderabbitai commentedon Jul 4, 2026
🔗 Related PRs
#330 - Fix/savegame component coverage [merged]
#405 - Codegen: generate the SaveGame component capture/restore lists (
#380) [merged]#467 - feat(codegen): SceneSerializer blocks for AssetHandle/UUID-field components (
#451) [merged]#477 - feat(codegen): SceneSerializer enum-field support (
#451slice) [merged]#482 - feat(codegen): SceneSerializer glm-math / small-int / std::vector support (
#451slice) [merged]🧪 Issue enrichment is currently in open beta.
To disable automatic issue enrichment, add the following to your
.coderabbit.yaml:💬 Have feedback or questions? Drop into our discord!