Found while upgrading HotCRM from @objectstack/* 17.4.0 to 17.5.0 in place (objectstack-ai/hotcrm#1970): 17.5.0 was booted on a SQLite database that 17.4.0 had created.
Symptom
Every objectstack dev boot, and every os migrate plan, prints this on the upgraded database:
Paged read of 'sys_migration' is NOT deterministic: this driver did not create the table, so it cannot name a unique column to order by, and the query asked for no sort of its own. Walking the pages may serve one row twice and never serve another (objectstack#4363). Give the query an `orderBy` on a unique column, or declare the object so this driver manages its table.
Control: 17.4.0 on the same database file prints nothing about sys_migration in three boots.
Why it is a false positive
The reads are the platform's own point lookups by primary key. Neither can return more than one row:
packages/metadata-protocol/src/migrations/seed-tenancy-backfill.ts, persistSeedTenancyReceiptRow: ledger.find(DATA_MIGRATION_FLAG_OBJECT, { where: { id: flag.id }, limit: 1, … })
packages/platform-objects/src/system/migration-flag.ts (~line 68): engine.find(DATA_MIGRATION_FLAG_OBJECT, { where: { id: migrationId }, limit: 1, … })
The limit: 1 makes the driver classify these as paged reads. On a table this driver instance did not create, the driver has no unique column to order by, so it warns. The warning then tells an operator to add an orderBy to a query that the operator did not write and cannot edit.
Impact
It is cosmetic, but it hits every in-place upgrade, on every boot. It is the first warning an upgrading operator sees, and its wording ("may serve one row twice and never serve another") reads as possible data loss in the migration ledger.
Suggested direction (not a ruling)
Either option would work:
- give the two lookups an explicit
orderBy: [{ field: 'id' }];
- have the determinism check skip a read whose
where pins a unique key with equality, since such a read has no pages to walk.
The second covers any other point lookup with the same shape.
Related: in the same upgraded database, os migrate plan also lists + sys_migration [add_columns: columns_moved_at] as pending. That is additive and expected. It is noted here only because it is the same table.
Found while upgrading HotCRM from
@objectstack/*17.4.0 to 17.5.0 in place (objectstack-ai/hotcrm#1970): 17.5.0 was booted on a SQLite database that 17.4.0 had created.Symptom
Every
objectstack devboot, and everyos migrate plan, prints this on the upgraded database:Control: 17.4.0 on the same database file prints nothing about
sys_migrationin three boots.Why it is a false positive
The reads are the platform's own point lookups by primary key. Neither can return more than one row:
packages/metadata-protocol/src/migrations/seed-tenancy-backfill.ts,persistSeedTenancyReceiptRow:ledger.find(DATA_MIGRATION_FLAG_OBJECT, { where: { id: flag.id }, limit: 1, … })packages/platform-objects/src/system/migration-flag.ts(~line 68):engine.find(DATA_MIGRATION_FLAG_OBJECT, { where: { id: migrationId }, limit: 1, … })The
limit: 1makes the driver classify these as paged reads. On a table this driver instance did not create, the driver has no unique column to order by, so it warns. The warning then tells an operator to add anorderByto a query that the operator did not write and cannot edit.Impact
It is cosmetic, but it hits every in-place upgrade, on every boot. It is the first warning an upgrading operator sees, and its wording ("may serve one row twice and never serve another") reads as possible data loss in the migration ledger.
Suggested direction (not a ruling)
Either option would work:
orderBy: [{ field: 'id' }];wherepins a unique key with equality, since such a read has no pages to walk.The second covers any other point lookup with the same shape.
Related: in the same upgraded database,
os migrate planalso lists+ sys_migration [add_columns: columns_moved_at]as pending. That is additive and expected. It is noted here only because it is the same table.