fixtures-invalid
"A section's fixtures.ts does not satisfy the fixture-module shape."
Venue: check — A section’s fixtures.ts does not satisfy the fixture-module shape.
fixtures.ts must export a named fixtures built from
defineFixtures — the value that call returns,
exported as-is:
export const fixtures = defineFixtures(schema, (scenario) => ({ base: scenario("luxuryMultiUnit", { … }) }));That value is branded, and the check verifies both halves of the claim: that the export carries the brand at all, and that what it carries is well-formed. The two failures read differently, on purpose.
Exporting a plain object — most often a hand-written { base: { slots: … } }
shape — fails the first check, and the message names the call to reach for:
Section "hero": fixtures.ts must export `fixtures` from a `defineFixtures(schema, …)` call. The hand-authored `{ base: { slots: … } }` shape isn't a valid module — build the module from a scenario instead: `defineFixtures(schema, (scenario) => ({ base: scenario(…) }))`.A branded module that is internally malformed fails the second, and each violation names
the exact path inside the module ("base", "base.slots", "states.empty-address", …)
and the shape expected there. In practice you reach this only by hand-writing the resolved
shape rather than calling defineFixtures.
A scenario that cannot supply a fact one of your slots needs is not this rule: that failure
throws while fixtures.ts loads, so it surfaces as
section-unrenderable, naming the scenario, the fact, and the
slot.
Reason
Section titled “Reason”The schema and the fill spec are both Zod-parsed on the way into every other check, so a
malformed one is caught immediately. fixtures.ts is the exception: nothing else parses
it, so without this gate a wrong shape would surface only once the render stage read it
directly — a raw crash mid-render, blamed on whatever line happened to dereference the
missing field, never on the fixture that was actually wrong.
This gate exists to move that failure to where the mistake was made, with a message about the fixture module instead of a stack trace from three files away.
Build the module with defineFixtures rather than writing its shape by hand. Everything
a hand-written shape would spell out — resolving each fact-bound slot, defaulting each
variant axis, tagging where every value came from — is what that call does for you.
Before
Section titled “Before”export const fixtures = { base: { slots: { headline: "A mansard Victorian in the heart of Jamaica Plain" }, }, states: { // A plain object skips defineFixtures entirely — no brand, no resolution. "long-headline": { slots: { headline: "A mansard Victorian with a terrazzo lobby, quartz kitchens throughout, and a top-floor penthouse", }, }, },};export const fixtures = defineFixtures( schema, (scenario) => ({ base: scenario("luxuryMultiUnit", { headline: "A mansard Victorian in the heart of Jamaica Plain", }), states: { // A state is COMPLETE, not a diff against base: it resolves from its own // `scenario()` call, so restate every authored slot it needs. Here that is // just `headline` — every fact-bound slot resolves on its own. "long-headline": scenario("luxuryMultiUnit", { headline: "A mansard Victorian with a terrazzo lobby, quartz kitchens throughout, and a top-floor penthouse", }), }, }),);See also
Section titled “See also”fixtures.ts— the fixtures declaration in full.schema-invalid— the sibling gate on the schema and fill spec, both insection.ts.bundle-incomplete— reported instead of this id whenfixtures.tsis missing outright, rather than present and wrong.