Diagnostics
Every diagnostic names the element it is about, the route it was found on, and prints a link to its entry on this page. Errors fail the build; warnings do not. Identical ones collapse into a single line with a count.
The full, untruncated list is written to rz/rasterize.diagnostics.json on every build.
| Code | Level | Condition |
|---|---|---|
| RZ001 | error | mix-blend-mode or backdrop-filter on a marked element |
| RZ002 | warn* | a transition or animation targets a baked property |
| RZ003 | warn | a baked value comes from a custom property that JS writes at runtime |
| RZ004 | error | flat mode but the size is not statically resolvable |
| RZ005 | error | a 9-slice stretch zone is not uniform |
| RZ006 | warn | texture budget exceeded, or a bake needs a bigger viewport than allowed |
| RZ007 | warn | the marked element has nothing worth baking |
| RZ008 | error | verification SSIM below the threshold |
| RZ009 | warn | the requested format cannot carry the alpha this asset needs |
| RZ010 | error | element mode, but nothing bakeable remains after exclusions |
| RZ011 | error | layout-affecting dynamism inside an element-mode subtree |
| RZ012 | warn | element mode: live parts were excluded (lists each one and why) |
| RZ013 | warn | layout-affecting media queries apply to this element |
| RZ014 | warn | a redundant nested marker, subsumed by an element-mode bake |
| RZ015 | info | an unmarked element uses expensive properties |
| RZ016 | warn | a state variant looks identical to the base bake |
| RZ017 | warn | the capture pass hit a problem with this element |
| RZ018 | warn | the element was display: none when it was captured |
| RZ019 | warn | the capture came back empty; nothing was baked and the live CSS was left alone |
| RZ020 | warn | lookalike elements baked differently and cannot all be matched |
| RZ021 | warn | several assets are byte-identical images under different ids |
| RZ022 | warn | marked elements have no texture in the built page |
| RZ023 | warn | the baked page differs from the live one by more than the threshold |
| RZ024 | warn | too small to 9-slice, so it was baked flat at its measured size |
| RZ025 | warn | a filter or mask survived the bake and still costs a pass every frame |
| RZ026 | warn | an element-mode subtree could not be flattened at build time, so a script ships |
* an error when strictTransitions: true.
What to do about them
Section titled “What to do about them”mix-blend-mode and backdrop-filter do not composite source-over, so no texture can reproduce
them against an arbitrary backdrop. There is no approximation mode. Remove the marker, or remove
the property.
A baked state variant is an instant swap, so a transition on a baked property disappears. Keep the element live, or accept the swap. See things to watch out for.
A 9-slice stretches its edges and centre, so anything varying along the stretched axis comes apart.
A gradient fill is the usual cause. Fixed-size elements can use data-rasterize-mode="flat" and
keep the gradient.
Either the total texture memory passed textureBudgetMB, and the message names the worst
offenders, or one asset needs a capture window larger than maxViewport. If your layout is sized
in vh, pin the root font size first — see preparing your UI.
Inside a flattened subtree, content can change what it shows but not how much space it takes.
data-bind-for and data-bind-if add and remove nodes, which moves everything after them. See
element mode.
Advisory only. Lists elements using expensive properties without a marker. It never marks anything.
The variant renders the same as the base bake, so it costs VRAM for no visual difference. Usually a
sign that data-rasterize-states was reached for to fix a matching problem, which it cannot do.
The element painted nothing when it was captured. Almost always a requestAnimationFrame loop
moving it mid-capture — see preparing your UI. The bake is refused rather than
shipped, because the emitted CSS also strips the live decoration, so an empty texture would leave
the element with nothing at all.
Several elements share a tag and class list but baked differently, and no ancestor class separates
them. Only one gets a texture. Move the variant onto the marked element itself —
.marker__frame--hostile rather than .marker--hostile .marker__frame.
One decoration baked twice. The message names which part of the bake key differs, usually the measured size. If the sizes should be equal, make them equal and the assets collapse into one.
Counted in the finished build by asking whether a generated selector matches each marked element. This is the check that catches a build being green while most of the page still runs live CSS. The message names the reason for each miss.
Every build renders itself twice, as shipped and with the bake stripped, and writes both plus their
difference to rz/report/. Look at the picture: green is live CSS, blue is what shipped, red is
where they disagree. Small differences are normal, since a rounded edge drawn from a texture and
the same edge drawn by the engine differ by a pixel of antialiasing.
When the element is narrower than its two corners put together there is nothing between them to
stretch, and border-image squashes the corner artwork. The bake is taken flat at the measured
size instead. A smaller blur or radius would let it slice properly.
filter and mask-image apply to content as well as decoration, so they can only be baked in when
nothing is left live to need them. This is a per-frame cost. If the whole subtree is static,
data-rasterize-mode="element" bakes it in and removes the pass — see
attributes.
An element-mode subtree that no HTML file contains, because a framework builds it at runtime. It gets a small script that flattens it once at load. Move the subtree into the HTML entry if you can; otherwise this is the cost of element mode in a framework, and it is one pass at load rather than anything per frame.
© 2026 Coherent Labs. All rights reserved.