Summary
The to v3.6.0 step in migrations/v3.js mutates getConfig()._spoor and writes _messages = {} there. However the schema change it is supposed to mirror — commit c1c50c87 — added _messages exclusively under pluginLocations.course._spoor, and the modern schema/course.schema.json keeps it on the course. config has never declared _messages.
So the migration targets a document where the field has no schema declaration and never touches the document where the field actually lives.
Schema (course): schema/course.schema.json — _spoor._messages is on the course.
Schema (config): schema/config.schema.json — no _messages anywhere.
Impact
The bug surfaces when something validates with strict types but without re-applying defaults, or when a present-but-wrong-typed value sits in the course doc from an older toolchain (e.g. an empty string instead of {}). I hit this in practice when importing a legacy course bundle into a v1 AAT: the import fails with /_spoor/_messages must be object.
Suggested fix
Retarget the migration to the course — swap getSpoorConfig() for getCourse() and update the test fixtures.
Summary
The
to v3.6.0step inmigrations/v3.jsmutatesgetConfig()._spoorand writes_messages = {}there. However the schema change it is supposed to mirror — commit c1c50c87 — added_messagesexclusively underpluginLocations.course._spoor, and the modernschema/course.schema.jsonkeeps it on the course.confighas never declared_messages.So the migration targets a document where the field has no schema declaration and never touches the document where the field actually lives.
Schema (course):
schema/course.schema.json—_spoor._messagesis on the course.Schema (config):
schema/config.schema.json— no_messagesanywhere.Impact
The bug surfaces when something validates with strict types but without re-applying defaults, or when a present-but-wrong-typed value sits in the course doc from an older toolchain (e.g. an empty string instead of
{}). I hit this in practice when importing a legacy course bundle into a v1 AAT: the import fails with/_spoor/_messages must be object.Suggested fix
Retarget the migration to the course — swap
getSpoorConfig()forgetCourse()and update the test fixtures.