Observation
101 test files partially mock @object-ui/react by hand-listing the exports the mock returns. 36 of them do so without importOriginal, so each mock's export surface is frozen at whatever the author typed the day they wrote it.
Every one of those 36 is a latent collection failure for the next export that any widely-imported module reads at module scope.
Why this shape is worth a card
It does not present as a normal test failure. Measured on PR #6767 (fixing #6678), where a registration helper newly read at module scope tripped it:
Error: [vitest] No "elementDataSourceBlock" export is defined on the "@object-ui/react" mock
at packages/.../record-picker.tsx:312
The suite reported:
Test Files 3 failed | 546 passed
Tests 6694 passed (6694)
Zero failed assertions. The files died at collection, so their tests never ran at all. All four shards were red for this reason — 17 of the 36 hand-listing mocks were in the import graph, which is why the failure was fleet-wide rather than a subset.
A red suite with zero failed assertions reads like flake or infrastructure. It is neither, and the hidden cost is real: after the seam moved, the same 549 files went from 6694 to 6727 passed — 33 tests that the uncollectable files could never have run.
Suggested durable fix
At those 36 sites, use the importOriginal form so the mock inherits the real export surface and overrides only what the test means to override:
vi.mock(import('@object-ui/react'), async (importOriginal) => {
const actual = await importOriginal();
return { ...actual, /* only the overrides this test needs */ };
});
The remaining 65 already do this and are not affected.
Scope
PR #6767 fixed its own instance — not by adding the export to 17 mocks (which leaves the hazard armed for the next module-scope addition) but by moving the seam to @object-ui/core, which nothing mocks and which all 17 call sites already imported. It also gated its own seam. The general shape is unowned, which is what this card records.
Duplicate check
Searched the repo for prior cards on vitest mocks / importOriginal / collection failures. Seven neighbours came back — #5899, #5365, #5160, #4585, #5360, #5048, #4538 — none of them this defect. The engine returning relevant neighbours is what makes the zero a reading rather than an empty query.
Observation
101 test files partially mock
@object-ui/reactby hand-listing the exports the mock returns. 36 of them do so withoutimportOriginal, so each mock's export surface is frozen at whatever the author typed the day they wrote it.Every one of those 36 is a latent collection failure for the next export that any widely-imported module reads at module scope.
Why this shape is worth a card
It does not present as a normal test failure. Measured on PR #6767 (fixing #6678), where a registration helper newly read at module scope tripped it:
The suite reported:
Zero failed assertions. The files died at collection, so their tests never ran at all. All four shards were red for this reason — 17 of the 36 hand-listing mocks were in the import graph, which is why the failure was fleet-wide rather than a subset.
A red suite with zero failed assertions reads like flake or infrastructure. It is neither, and the hidden cost is real: after the seam moved, the same 549 files went from
6694to6727passed — 33 tests that the uncollectable files could never have run.Suggested durable fix
At those 36 sites, use the
importOriginalform so the mock inherits the real export surface and overrides only what the test means to override:The remaining 65 already do this and are not affected.
Scope
PR #6767 fixed its own instance — not by adding the export to 17 mocks (which leaves the hazard armed for the next module-scope addition) but by moving the seam to
@object-ui/core, which nothing mocks and which all 17 call sites already imported. It also gated its own seam. The general shape is unowned, which is what this card records.Duplicate check
Searched the repo for prior cards on vitest mocks /
importOriginal/ collection failures. Seven neighbours came back — #5899, #5365, #5160, #4585, #5360, #5048, #4538 — none of them this defect. The engine returning relevant neighbours is what makes the zero a reading rather than an empty query.