A predictor that guesses wrong destroys trust in every number beside it. So anything not lexically
determinable is reported as unknown rather than resolved to a plausible answer.
What gets reported as unknown
- A component arriving through
children or held in a variable, outside a layout — the
layout.tsx → page.tsx relationship is resolvable by file convention, so layouts are not
flagged
- A component name defined in more than one file, where the render site cannot disambiguate
- A boundary child that resolves to no source file — usually a dependency’s component
export const dynamic = … computed at runtime rather than written as a literal
Where the prediction is deliberately coarse
Taint propagation is module-level: if a file transitively reaches something dynamic, the file is
tainted. That is coarser than function-level, but it errs toward reporting dynamism, never toward
claiming something is static when it is not.
Module-level taint must not condemn a component outright. Inferring that a component is dynamic
because its file imports something dynamic reported <RootLayout> as a hole on every route of a
real 25-route app — true under module granularity, and useless. Transitive taint decides boundary
children; it does not condemn a component on its own.
Rendering mode
When a route is not prerendered and no dynamic API appears in source, crust reports unknown with
the reason attached, rather than assuming DYNAMIC.
Attribution
A chunk with no source map is reported as unattributed bytes with the reason
no source map emitted for this chunk. Repeated instances collapse into one line naming the fix —
a list of 673 identical warnings buries every other warning and teaches people to skip the section.