Appearance
Debugging & Diagnostics
Use the debugging utilities when an SVG looks different from the layout you expected, when multiple generated scenes are composed into one document, or when CI needs to reject unstable node IDs before assets are released.
Visual Bounds
The fastest first check is the render-time debug overlay:
tsx
const vnode = (
<Canvas width={420} height={180} background="#0f172a">
<Flex
id="preview"
direction="row"
gap={14}
width={420}
height={180}
padding={18}
alignItems="center"
>
<Box
id="thumbnail"
width={128}
height={120}
background="#155e75"
borderRadius={8}
/>
<Flex id="copy" direction="column" gap={8} width={230}>
<Text id="title" font="NotoSansJP" fontSizePx={22} color="#f8fafc">
Inspect a scene
</Text>
<Text
id="body"
font="NotoSansJP"
fontSizePx={14}
color="#cbd5e1"
preferredFrame={{ w: 220 }}
wrap="word"
>
Check bboxes, draw order, handlers, warnings, and text overflow.
</Text>
</Flex>
</Flex>
</Canvas>
);
const svg = engine.renderToSvg(vnode, { debug: true });Generated SVG
xml
<svg xmlns="http://www.w3.org/2000/svg" data-boundsvg-node-id="auto:0" viewBox="0 0 420 180" width="420" height="180">
<rect x="0" y="0" width="420" height="180" fill="#0f172a"/>
<g data-boundsvg-node-id="preview">
<g data-boundsvg-node-id="thumbnail">
<rect x="18" y="30" width="128" height="120" rx="8" ry="8" fill="#155e75"/>
</g>
<g data-boundsvg-node-id="copy">
<g data-boundsvg-node-id="title">
<g data-boundsvg-node-id="title" data-boundsvg-text="Inspect a scene" aria-label="Inspect a scene">
<path d="M162.22 69.56V53.43h2.03V69.56zM168.47 69.56V57.61h1.65l.2 1.74h.04q.86-.86 1.82-1.45.95-.59 2.19-.59q1.89 0 2.77 1.2.88 1.19.88 3.48v7.57h-2v-7.3q0-1.7-.54-2.45-.54-.74-1.73-.74-.92 0-1.65.46t-1.61 1.36v8.67zM185.01 69.85q-1.25 0-2.43-.48-1.17-.47-2.01-1.17l.97-1.35q.79.64 1.63 1.04.83.39 1.91.39q1.19 0 1.77-.53.58-.54.58-1.34q0-.61-.4-1.02-.41-.41-1.04-.7-.62-.3-1.28-.54-.84-.33-1.64-.74-.81-.41-1.32-1.05-.52-.65-.52-1.67q0-.96.48-1.72.49-.76 1.41-1.21.93-.45 2.22-.45q1.1 0 2.06.39.96.4 1.64.97l-.97 1.25q-.61-.44-1.26-.74-.65-.31-1.44-.31-1.15 0-1.69.52-.54.51-.54 1.22q0 .55.37.92.36.37.95.63.6.25 1.26.51.66.25 1.31.53.65.29 1.16.68.52.4.84.98.32.59.32 1.44q0 .97-.5 1.79-.49.81-1.45 1.28-.96.48-2.39.48zM192.19 74.6V57.61h1.65l.19 1.39h.05q.81-.68 1.79-1.19.98-.5 2.01-.5q1.54 0 2.61.76q1.07.75 1.61 2.12.54 1.36.54 3.21q0 2.05-.74 3.49t-1.91 2.2q-1.18.76-2.55.76-.81 0-1.65-.37-.83-.36-1.65-1.02l.07 2.09V74.6zM197.11 68.15q.99 0 1.77-.56.79-.56 1.23-1.63.44-1.06.44-2.54q0-1.32-.32-2.32t-1-1.55q-.69-.55-1.85-.55-.75 0-1.53.42t-1.64 1.21v6.29q.79.68 1.56.96.77.27 1.34.27zM210.67 69.85q-1.61 0-2.91-.75t-2.06-2.15q-.75-1.39-.75-3.35q0-1.48.44-2.63.44-1.16 1.19-1.98.76-.83 1.73-1.26.97-.42 1.98-.42q1.54 0 2.6.68q1.05.68 1.61 1.95.57 1.26.57 2.98q0 .33-.03.61-.02.29-.06.53h-8.05q.06 1.28.58 2.21.52.94 1.37 1.45.86.52 2.01.52.88 0 1.59-.25.72-.26 1.4-.7l.7 1.35q-.77.5-1.74.85-.96.36-2.17.36zM206.9 62.63h6.41q0-1.8-.79-2.76-.78-.96-2.18-.96-.84 0-1.58.44-.73.44-1.23 1.26-.49.81-.63 2.02zM222.72 69.85q-1.58 0-2.85-.74-1.26-.74-2-2.13-.74-1.4-.74-3.38q0-2 .8-3.4.79-1.4 2.11-2.15q1.32-.74 2.84-.74q1.16 0 2.01.41.85.42 1.46.99l-1.01 1.32q-.51-.46-1.09-.74-.58-.29-1.29-.29-1.07 0-1.93.57t-1.34 1.61q-.49 1.03-.49 2.42q0 1.36.48 2.4.47 1.03 1.29 1.6.83.57 1.93.57.83 0 1.54-.34.7-.34 1.27-.84l.88 1.36q-.81.7-1.8 1.1t-2.07.4zM232.67 69.85q-1.26 0-2.01-.5-.74-.49-1.06-1.4-.32-.9-.32-2.09V59.24H227.5V57.72l1.89-.11.22-3.36h1.67v3.36h3.26v1.63h-3.26v6.69q0 1.08.41 1.68.4.61 1.44.61.33 0 .7-.1.38-.1.66-.23l.4 1.52q-.51.17-1.08.3-.57.14-1.14.14zM244.9 69.85q-.99 0-1.78-.4-.8-.4-1.25-1.15-.45-.76-.45-1.84q0-1.96 1.75-3q1.75-1.05 5.58-1.47q0-.77-.21-1.46t-.74-1.12-1.52-.43q-1.03 0-1.94.41-.92.4-1.64.86l-.77-1.38q.55-.35 1.27-.72.73-.36 1.59-.6t1.82-.24q1.46 0 2.37.61.91.62 1.34 1.71t.43 2.58v7.35H249.1l-.18-1.43h-.06q-.84.7-1.84 1.21t-2.12.51zM245.47 68.22q.86 0 1.64-.4.78-.39 1.64-1.16V63.33q-2 .22-3.19.63t-1.7.99q-.5.58-.5 1.38q0 1.03.61 1.46.62.43 1.5.43zM262.59 69.85q-1.26 0-2.44-.48-1.17-.47-2.01-1.17l.97-1.35q.79.64 1.63 1.04.83.39 1.91.39q1.19 0 1.77-.53.59-.54.59-1.34q0-.61-.41-1.02t-1.04-.7q-.62-.3-1.28-.54-.84-.33-1.64-.74t-1.32-1.05q-.52-.65-.52-1.67q0-.96.49-1.72.48-.76 1.4-1.21.93-.45 2.23-.45q1.1 0 2.05.39.96.4 1.64.97l-.97 1.25q-.61-.44-1.26-.74-.65-.31-1.44-.31-1.15 0-1.69.52-.53.51-.53 1.22q0 .55.36.92t.96.63q.59.25 1.25.51.66.25 1.31.53.65.29 1.16.68.52.4.84.98.32.59.32 1.44q0 .97-.49 1.79-.5.81-1.46 1.28-.95.48-2.38.48zM274.47 69.85q-1.59 0-2.85-.74-1.27-.74-2.01-2.13-.73-1.4-.73-3.38q0-2 .79-3.4t2.11-2.15q1.32-.74 2.84-.74q1.17 0 2.01.41.85.42 1.47.99l-1.02 1.32q-.5-.46-1.08-.74-.59-.29-1.29-.29-1.08 0-1.94.57t-1.34 1.61q-.48 1.03-.48 2.42q0 1.36.47 2.4.47 1.03 1.3 1.6.82.57 1.92.57.84 0 1.54-.34.71-.34 1.28-.84l.88 1.36q-.82.7-1.81 1.1t-2.06.4zM285.22 69.85q-1.6 0-2.9-.75t-2.06-2.15q-.76-1.39-.76-3.35q0-1.48.44-2.63.44-1.16 1.2-1.98.76-.83 1.73-1.26.97-.42 1.98-.42q1.54 0 2.6.68q1.05.68 1.61 1.95.56 1.26.56 2.98q0 .33-.02.61-.02.29-.06.53h-8.06q.07 1.28.59 2.21.51.94 1.37 1.45.86.52 2 .52.88 0 1.6-.25.71-.26 1.4-.7l.7 1.35q-.77.5-1.74.85-.97.36-2.18.36zM281.46 62.63h6.4q0-1.8-.78-2.76t-2.19-.96q-.83 0-1.57.44t-1.23 1.26q-.5.81-.63 2.02zM292.57 69.56V57.61h1.65l.2 1.74h.04q.86-.86 1.82-1.45t2.19-.59q1.89 0 2.77 1.2.88 1.19.88 3.48v7.57h-2v-7.3q0-1.7-.54-2.45-.54-.74-1.73-.74-.92 0-1.65.46-.72.46-1.6 1.36v8.67zM310.83 69.85q-1.6 0-2.9-.75t-2.06-2.15q-.76-1.39-.76-3.35q0-1.48.44-2.63.44-1.16 1.2-1.98.76-.83 1.73-1.26.97-.42 1.98-.42q1.54 0 2.59.68q1.06.68 1.62 1.95.56 1.26.56 2.98q0 .33-.02.61-.02.29-.07.53h-8.05q.07 1.28.58 2.21.52.94 1.38 1.45.86.52 2 .52.88 0 1.6-.25.71-.26 1.39-.7l.71 1.35q-.77.5-1.74.85-.97.36-2.18.36zM307.07 62.63h6.4q0-1.8-.78-2.76t-2.19-.96q-.83 0-1.57.44t-1.23 1.26q-.5.81-.63 2.02z" fill="#f8fafc"/>
</g>
</g>
<g data-boundsvg-node-id="body">
<g data-boundsvg-node-id="body" data-boundsvg-text="Check bboxes, draw order,
handlers, warnings, and text
overflow." aria-label="Check bboxes, draw order,
handlers, warnings, and text
overflow.">
<path d="M165.28 95.9q-.95 0-1.77-.35-.82-.36-1.42-1.05-.61-.68-.94-1.67-.34-.99-.34-2.23q0-1.25.35-2.24.34-.98.95-1.67.62-.69 1.45-1.05.82-.36 1.8-.36.94 0 1.65.38.72.39 1.17.88l-.7.84q-.41-.44-.93-.7-.52-.27-1.17-.27-.97 0-1.7.5-.73.51-1.13 1.44-.41.93-.41 2.2q0 1.31.39 2.25.4.95 1.11 1.46t1.69.51q.73 0 1.31-.31t1.07-.85l.72.82q-.6.7-1.37 1.09-.77.38-1.78.38zM170.22 95.72V84.58h1.29v3.05l-.06 1.57q.53-.54 1.14-.91.6-.37 1.38-.37q1.21 0 1.77.77.56.76.56 2.21v4.82h-1.28V91.07q0-1.08-.34-1.55-.34-.48-1.1-.48-.59 0-1.05.3-.46.29-1.02.86v5.52zM181.8 95.9q-1.02 0-1.85-.47-.83-.48-1.31-1.37t-.48-2.13q0-.94.28-1.68.28-.73.76-1.26.48-.52 1.1-.8.62-.27 1.26-.27.98 0 1.65.44.67.43 1.03 1.23.36.81.36 1.9q0 .21-.02.39-.01.19-.04.34h-5.12q.04.81.37 1.41.33.59.87.92.55.33 1.28.33.56 0 1.01-.16.46-.16.89-.44l.45.85q-.49.32-1.11.55-.61.22-1.38.22zM179.4 91.31h4.08q0-1.15-.5-1.76t-1.39-.61q-.53 0-1 .28t-.79.8q-.31.52-.4 1.29zM189.47 95.9q-1.01 0-1.81-.47-.81-.47-1.28-1.35-.47-.89-.47-2.15q0-1.28.51-2.17.5-.89 1.34-1.36.84-.48 1.81-.48.74 0 1.28.27.54.26.93.63l-.64.84q-.33-.3-.7-.48t-.82-.18q-.68 0-1.23.36-.54.37-.85 1.03-.31.65-.31 1.54q0 .86.3 1.52t.83 1.02q.52.37 1.22.37.53 0 .98-.22t.81-.54l.56.87q-.51.45-1.14.7t-1.32.25zM193.61 95.72V84.58h1.26v7.54h.06l3.22-4h1.43l-2.54 3.06l2.87 4.54h-1.38l-2.23-3.67-1.43 1.67v2zM207.82 95.9q-.51 0-1.09-.25-.57-.25-1.06-.71h-.06l-.11.78h-1.02V84.58h1.29v3.05l-.06 1.36q.52-.45 1.13-.76.62-.31 1.26-.31.98 0 1.66.49.67.48 1.02 1.35.35.86.35 2.04q0 1.29-.47 2.21-.47.93-1.22 1.41t-1.62.48zM207.61 94.82q.63 0 1.13-.35.5-.36.78-1.04t.28-1.62q0-.84-.21-1.47-.2-.64-.63-.99-.44-.35-1.18-.35-.47 0-.98.27-.5.26-1.03.77v4q.49.43.98.61.5.17.86.17zM216.48 95.9q-.52 0-1.1-.25-.57-.25-1.06-.71h-.06l-.11.78h-1.02V84.58h1.29v3.05l-.06 1.36q.52-.45 1.14-.76.61-.31 1.26-.31.98 0 1.65.49.67.48 1.02 1.35.35.86.35 2.04q0 1.29-.47 2.21-.47.93-1.22 1.41t-1.61.48zM216.27 94.82q.63 0 1.12-.35.5-.36.78-1.04t.28-1.62q0-.84-.2-1.47-.21-.64-.64-.99T216.43 89q-.47 0-.98.27-.5.26-1.03.77v4q.49.43.99.61.49.17.86.17zM224.74 95.9q-.93 0-1.74-.47t-1.29-1.35q-.49-.89-.49-2.15q0-1.28.49-2.17.48-.89 1.29-1.36.81-.48 1.74-.48.7 0 1.33.27.64.26 1.13.78t.77 1.26.28 1.7q0 1.26-.49 2.15-.49.88-1.29 1.35t-1.73.47zM224.74 94.84q.65 0 1.15-.37.5-.36.78-1.02t.28-1.52q0-.89-.28-1.54-.28-.66-.78-1.03-.5-.36-1.15-.36-.66 0-1.16.36-.5.37-.77 1.03-.27.65-.27 1.54q0 .86.27 1.52t.77 1.02q.5.37 1.16.37zM228.88 95.72l2.51-3.96-2.31-3.64h1.38l1.02 1.66q.17.33.36.64.19.32.39.64h.07q.15-.32.32-.64.18-.31.35-.64l.94-1.66h1.33l-2.31 3.76l2.5 3.84h-1.4l-1.12-1.78q-.19-.35-.4-.69-.2-.34-.42-.67h-.07q-.19.33-.38.67-.18.34-.39.69l-1.03 1.78zM239.7 95.9q-1.02 0-1.85-.47-.82-.48-1.3-1.37-.49-.89-.49-2.13q0-.94.28-1.68.28-.73.76-1.26.49-.52 1.1-.8.62-.27 1.26-.27.98 0 1.66.44.67.43 1.03 1.23.35.81.35 1.9q0 .21-.01.39-.02.19-.04.34h-5.13q.04.81.37 1.41.33.59.88.92.54.33 1.27.33.56 0 1.02-.16.45-.16.89-.44l.44.85q-.49.32-1.1.55-.62.22-1.39.22zM237.31 91.31h4.07q0-1.15-.5-1.76-.49-.61-1.39-.61-.53 0-1 .28t-.78.8q-.32.52-.4 1.29zM246.37 95.9q-.8 0-1.55-.3t-1.28-.75l.61-.85q.51.4 1.04.66.53.25 1.22.25.75 0 1.12-.35.38-.34.38-.84q0-.39-.26-.65t-.66-.45-.82-.34q-.53-.21-1.04-.47t-.84-.67q-.33-.42-.33-1.06q0-.62.31-1.1.3-.48.89-.77t1.42-.29q.7 0 1.3.25.61.26 1.05.62l-.62.8q-.39-.28-.8-.48-.42-.19-.92-.19-.73 0-1.07.33-.34.32-.34.77q0 .35.23.59t.61.4q.37.16.79.33.42.15.84.33.41.19.74.44t.53.62.2.92q0 .61-.31 1.13-.32.52-.93.82-.6.3-1.51.3zM250.69 98.38l-.31-.76q.66-.29 1.04-.79.38-.51.36-1.15l-.14-1.15.63.94q-.14.15-.3.22-.16.06-.34.06-.38 0-.66-.24t-.28-.66.29-.66q.29-.23.68-.23.5 0 .79.4.29.39.29 1.09q0 1.01-.56 1.77-.55.75-1.49 1.16zM260.55 95.9q-.95 0-1.66-.46t-1.09-1.35q-.39-.89-.39-2.16q0-1.24.46-2.13.47-.9 1.22-1.39.74-.49 1.61-.49.67 0 1.16.23.48.23.98.65l-.07-1.3V84.58h1.29V95.72h-1.05l-.11-.9h-.04q-.45.45-1.04.77-.59.31-1.27.31zM260.83 94.82q.53 0 1.01-.26.47-.25.93-.77V89.8q-.47-.44-.92-.62t-.92-.18q-.61 0-1.1.37-.5.37-.8 1.02t-.3 1.52q0 .91.25 1.57t.72 1t1.13.34zM266.64 95.72v-7.6h1.05l.12 1.38h.03q.39-.72.96-1.15t1.2-.43q.26 0 .45.04.19.03.36.13l-.24 1.11q-.19-.06-.35-.09-.15-.04-.39-.04-.46 0-.99.4-.54.4-.91 1.36v4.89zM273.41 95.9q-.63 0-1.13-.25t-.79-.74q-.29-.48-.29-1.16q0-1.25 1.11-1.92q1.12-.66 3.55-.93q0-.49-.13-.93t-.47-.71q-.33-.27-.96-.27-.66 0-1.24.26-.58.25-1.05.55l-.49-.88q.35-.23.82-.46.46-.23 1-.38.55-.16 1.17-.16.92 0 1.5.39.58.4.85 1.09.28.69.28 1.64v4.68h-1.05l-.11-.91h-.05q-.53.45-1.17.77-.63.32-1.35.32zM273.78 94.87q.54 0 1.04-.26.5-.25 1.04-.74V91.76q-1.27.14-2.03.4-.75.26-1.07.63-.33.37-.33.87q0 .66.4.93.39.28.95.28zM280.75 95.72l-2.11-7.6h1.3l1.13 4.39q.13.55.23 1.07.11.52.22 1.05h.07q.13-.53.24-1.05.12-.52.26-1.07l1.19-4.39h1.25l1.19 4.39q.14.55.27 1.07.14.52.26 1.05h.07q.11-.53.23-1.05.11-.52.23-1.07l1.11-4.39h1.23l-2.06 7.6h-1.55l-1.09-4.1q-.14-.53-.27-1.07-.12-.54-.25-1.12h-.07q-.13.58-.25 1.12-.11.55-.27 1.1l-1.08 4.07zM296.86 95.9q-.92 0-1.73-.47t-1.3-1.35q-.48-.89-.48-2.15q0-1.28.48-2.17.49-.89 1.3-1.36.81-.48 1.73-.48.7 0 1.34.27.64.26 1.13.78t.77 1.26.28 1.7q0 1.26-.49 2.15-.49.88-1.29 1.35t-1.74.47zM296.86 94.84q.66 0 1.16-.37.5-.36.78-1.02t.28-1.52q0-.89-.28-1.54-.28-.66-.78-1.03-.5-.36-1.16-.36-.65 0-1.15.36-.5.37-.77 1.03-.27.65-.27 1.54q0 .86.27 1.52t.77 1.02q.5.37 1.15.37zM302.39 95.72v-7.6h1.05l.13 1.38h.03q.39-.72.96-1.15.56-.43 1.19-.43.27 0 .46.04.19.03.36.13l-.24 1.11q-.2-.06-.35-.09-.16-.04-.39-.04-.47 0-1 .4t-.91 1.36v4.89zM310.22 95.9q-.95 0-1.66-.46t-1.09-1.35q-.39-.89-.39-2.16q0-1.24.47-2.13.46-.9 1.21-1.39t1.61-.49q.68 0 1.16.23t.99.65l-.07-1.3V84.58h1.28V95.72h-1.05l-.11-.9h-.04q-.45.45-1.04.77-.58.31-1.27.31zM310.5 94.82q.53 0 1.01-.26.47-.25.94-.77V89.8q-.48-.44-.93-.62T310.6 89q-.6 0-1.1.37t-.8 1.02-.3 1.52q0 .91.25 1.57t.72 1t1.13.34zM319.39 95.9q-1.02 0-1.85-.47-.82-.48-1.31-1.37-.48-.89-.48-2.13q0-.94.28-1.68.28-.73.76-1.26.49-.52 1.1-.8.62-.27 1.26-.27.98 0 1.65.44.68.43 1.03 1.23.36.81.36 1.9q0 .21-.01.39-.02.19-.05.34h-5.12q.04.81.37 1.41.33.59.88.92.54.33 1.27.33.56 0 1.02-.16.45-.16.88-.44l.45.85q-.49.32-1.1.55-.62.22-1.39.22zM317 91.31h4.07q0-1.15-.5-1.76-.49-.61-1.39-.61-.53 0-1 .28t-.79.8q-.31.52-.39 1.29zM324.07 95.72v-7.6h1.05l.12 1.38h.03q.39-.72.96-1.15t1.2-.43q.26 0 .45.04.19.03.36.13L328 89.2q-.2-.06-.35-.09-.15-.04-.39-.04-.46 0-1 .4-.53.4-.91 1.36v4.89zM328.36 98.38l-.3-.76q.65-.29 1.03-.79.38-.51.37-1.15l-.14-1.15.63.94q-.14.15-.31.22-.16.06-.34.06-.38 0-.66-.24t-.28-.66.29-.66q.29-.23.68-.23.5 0 .79.4.29.39.29 1.09q0 1.01-.56 1.77-.55.75-1.49 1.16zM161.29 112.52V101.38h1.29v3.05l-.06 1.57q.53-.54 1.13-.91.61-.37 1.39-.37q1.2 0 1.76.76.56.77.56 2.22v4.82h-1.27v-4.65q0-1.08-.34-1.55-.35-.48-1.1-.48-.59 0-1.05.3-.46.29-1.02.86v5.52zM171.54 112.7q-.63 0-1.14-.25-.5-.25-.79-.74-.29-.48-.29-1.16q0-1.25 1.12-1.92q1.11-.66 3.55-.93q0-.49-.14-.93-.13-.44-.47-.71-.33-.27-.96-.27-.66 0-1.24.26-.58.25-1.04.55l-.49-.88q.35-.23.81-.46t1.01-.38q.54-.16 1.16-.16.92 0 1.5.39.58.4.86 1.09.27.69.27 1.64v4.68h-1.05l-.11-.91h-.04q-.54.45-1.17.77-.64.32-1.35.32zM171.9 111.67q.55 0 1.04-.26.5-.25 1.05-.74v-2.11q-1.28.14-2.03.4-.76.26-1.08.63t-.32.87q0 .66.39.93.39.28.95.28zM177.67 112.52v-7.6h1.05l.12 1.1h.03q.55-.54 1.16-.92t1.39-.38q1.2 0 1.76.76.56.77.56 2.22v4.82h-1.27v-4.65q0-1.08-.34-1.55-.35-.48-1.1-.48-.59 0-1.05.3-.46.29-1.02.86v5.52zM188.8 112.7q-.95 0-1.66-.46t-1.09-1.35q-.39-.89-.39-2.16q0-1.24.46-2.13.47-.9 1.21-1.39.75-.49 1.62-.49.67 0 1.16.23.48.23.98.65l-.07-1.3v-2.92h1.29v11.14h-1.05l-.11-.9h-.04q-.45.45-1.04.77-.59.31-1.27.31zM189.08 111.62q.53 0 1.01-.26.47-.25.93-.77V106.6q-.47-.44-.92-.62t-.92-.18q-.61 0-1.1.37-.5.37-.8 1.02t-.3 1.52q0 .91.25 1.57t.72 1t1.13.34zM196.23 112.7q-.47 0-.77-.19-.29-.2-.43-.59-.14-.38-.14-.91v-9.63h1.29v9.71q0 .3.1.42.11.13.25.13.05 0 .11-.01.05-.01.15-.02l.18.98q-.14.04-.3.08-.17.03-.44.03zM201.94 112.7q-1.02 0-1.84-.47-.83-.48-1.31-1.37-.49-.89-.49-2.13q0-.94.28-1.68.28-.73.77-1.26.48-.52 1.1-.8.61-.27 1.26-.27.98 0 1.65.44.67.43 1.03 1.23.35.81.35 1.9q0 .21-.01.39-.01.19-.04.34h-5.13q.05.81.38 1.41.32.59.87.92t1.27.33q.56 0 1.02-.16.45-.16.89-.44l.45.85q-.49.32-1.11.55-.62.22-1.39.22zM199.55 108.11h4.07q0-1.15-.49-1.76-.5-.61-1.4-.61-.53 0-1 .28t-.78.8q-.32.52-.4 1.29zM206.62 112.52v-7.6h1.05l.13 1.38h.02q.4-.72.96-1.15.57-.43 1.2-.43.27 0 .46.04.18.03.35.13l-.24 1.11q-.19-.06-.35-.09-.15-.04-.39-.04-.46 0-.99.4t-.91 1.36v4.89zM213.94 112.7q-.8 0-1.54-.3-.75-.3-1.29-.75l.62-.85q.5.4 1.04.66.53.25 1.21.25.76 0 1.13-.35.37-.34.37-.84q0-.39-.26-.65t-.66-.45q-.39-.19-.81-.34-.54-.21-1.05-.47t-.84-.67q-.33-.42-.33-1.06q0-.62.31-1.1t.9-.77t1.41-.29q.7 0 1.31.25.61.26 1.04.62l-.61.8q-.39-.28-.81-.48-.41-.19-.91-.19-.73 0-1.08.33-.34.32-.34.77q0 .35.23.59t.61.4.8.33q.42.15.83.33.42.19.75.44.32.25.53.62.2.37.2.92q0 .61-.32 1.13-.31.52-.92.82t-1.52.3zM218.27 115.18l-.31-.76q.66-.29 1.04-.79.37-.51.36-1.15l-.14-1.15.63.94q-.14.15-.3.21-.16.07-.34.07-.38 0-.66-.24t-.28-.66.28-.66q.29-.23.68-.23.51 0 .79.4.29.39.29 1.09q0 1.01-.55 1.77-.55.75-1.49 1.16zM226.74 112.52l-2.12-7.6h1.31l1.13 4.39q.13.55.23 1.07.11.52.22 1.05h.07q.12-.53.24-1.05t.26-1.07l1.19-4.39h1.25l1.19 4.39q.14.55.27 1.07t.26 1.05h.07q.11-.53.22-1.05.12-.52.24-1.07l1.11-4.39h1.23l-2.06 7.6H231.5l-1.09-4.1q-.14-.53-.27-1.07t-.25-1.12h-.07q-.13.58-.25 1.12-.12.55-.27 1.1l-1.08 4.07zM238.32 112.7q-.63 0-1.14-.25-.5-.25-.79-.74-.29-.48-.29-1.16q0-1.25 1.12-1.92q1.11-.66 3.55-.93q0-.49-.14-.93-.13-.44-.47-.71-.33-.27-.96-.27-.66 0-1.24.26-.58.25-1.04.55l-.49-.88q.35-.23.81-.46t1.01-.38q.54-.16 1.16-.16.92 0 1.5.39.58.4.86 1.09.27.69.27 1.64v4.68h-1.05l-.11-.91h-.04q-.54.45-1.17.77-.64.32-1.35.32zM238.68 111.67q.55 0 1.04-.26.5-.25 1.05-.74v-2.11q-1.28.14-2.03.4-.76.26-1.08.63t-.32.87q0 .66.39.93.39.28.95.28zM244.45 112.52v-7.6h1.05l.12 1.38h.03q.39-.72.96-1.15t1.2-.43q.26 0 .45.04.19.03.36.13l-.24 1.11q-.19-.06-.35-.09-.15-.04-.39-.04-.46 0-.99.4-.54.4-.91 1.36v4.89zM249.88 112.52v-7.6h1.05l.13 1.1h.02q.55-.54 1.16-.92t1.39-.38q1.21 0 1.77.76.56.77.56 2.22v4.82h-1.28v-4.65q0-1.08-.34-1.55-.34-.48-1.1-.48-.59 0-1.05.3-.46.29-1.02.86v5.52zM258.42 112.52v-7.6h1.29v7.6zM259.06 103.35q-.37 0-.61-.23-.23-.23-.23-.62q0-.38.23-.61.24-.22.61-.22.38 0 .62.22.24.23.24.61q0 .39-.24.62t-.62.23zM262.27 112.52v-7.6h1.05l.13 1.1h.02q.55-.54 1.16-.92t1.39-.38q1.21 0 1.77.76.56.77.56 2.22v4.82h-1.28v-4.65q0-1.08-.34-1.55-.34-.48-1.1-.48-.59 0-1.05.3-.46.29-1.02.86v5.52zM273.37 116.02q-.92 0-1.64-.24-.71-.24-1.1-.69-.39-.46-.39-1.1q0-.49.29-.94.29-.46.83-.78v-.07q-.3-.18-.49-.49-.2-.31-.2-.76q0-.47.27-.84.28-.36.57-.57v-.06q-.38-.29-.69-.82-.3-.54-.3-1.22q0-.84.39-1.45t1.04-.94t1.41-.33q.33 0 .61.06.27.05.47.14h2.64v.98h-1.55q.28.26.45.67.16.41.16.9q0 .81-.37 1.4-.37.6-1 .92t-1.41.32q-.27 0-.57-.07t-.55-.19q-.21.16-.35.37t-.14.54q0 .35.28.58.28.24 1.05.24h1.5q1.31 0 1.98.44.66.43.66 1.37q0 .7-.47 1.3-.48.6-1.34.97-.86.36-2.04.36zM273.36 109.24q.45 0 .82-.22t.59-.63q.21-.41.21-.95q0-.56-.21-.96-.22-.4-.59-.61-.36-.21-.82-.21-.44 0-.81.21t-.58.6q-.22.39-.22.97q0 .54.22.95.23.41.59.63t.8.22zM273.55 115.14q.73 0 1.27-.23.54-.22.84-.58.3-.35.3-.73q0-.55-.39-.76t-1.15-.21h-1.31q-.21 0-.47-.02t-.51-.09q-.41.28-.59.62-.18.35-.18.67q0 .6.58.96.58.37 1.61.37zM280.69 112.7q-.79 0-1.54-.3t-1.28-.75l.61-.85q.51.4 1.04.66.53.25 1.22.25.75 0 1.12-.35.37-.34.37-.84q0-.39-.25-.65-.26-.26-.66-.45t-.82-.34q-.53-.21-1.05-.47-.51-.26-.83-.67-.33-.42-.33-1.06q0-.62.3-1.1.31-.48.9-.77t1.41-.29q.7 0 1.31.25.61.26 1.05.62l-.62.8q-.39-.28-.81-.48-.41-.19-.91-.19-.73 0-1.07.33-.35.32-.35.77q0 .35.24.59.23.24.6.4.38.16.8.33.42.15.84.33.41.19.74.44t.53.62.2.92q0 .61-.31 1.13-.32.52-.93.82t-1.52.3zM285.02 115.18l-.31-.76q.66-.29 1.04-.79.38-.51.36-1.15l-.14-1.15.63.94q-.14.15-.3.21-.16.07-.34.07-.38 0-.66-.24t-.28-.66.29-.66q.28-.23.68-.23.5 0 .79.4.28.39.28 1.09q0 1.01-.55 1.77-.55.75-1.49 1.16zM294.04 112.7q-.63 0-1.14-.25-.5-.25-.79-.74-.29-.48-.29-1.16q0-1.25 1.12-1.92q1.11-.66 3.55-.93q0-.49-.14-.93-.13-.44-.47-.71-.33-.27-.96-.27-.66 0-1.24.26-.58.25-1.04.55l-.49-.88q.35-.23.81-.46t1.01-.38q.54-.16 1.16-.16.92 0 1.5.39.58.4.86 1.09.27.69.27 1.64v4.68h-1.05l-.11-.91h-.04q-.54.45-1.17.77-.64.32-1.35.32zM294.4 111.67q.55 0 1.04-.26.5-.25 1.05-.74v-2.11q-1.28.14-2.03.4-.76.26-1.08.63t-.32.87q0 .66.39.93.39.28.95.28zM300.17 112.52v-7.6h1.05l.12 1.1h.03q.55-.54 1.16-.92t1.39-.38q1.2 0 1.76.76.56.77.56 2.22v4.82h-1.27v-4.65q0-1.08-.34-1.55-.35-.48-1.1-.48-.59 0-1.05.3-.46.29-1.02.86v5.52zM311.3 112.7q-.95 0-1.66-.46t-1.09-1.35q-.39-.89-.39-2.16q0-1.24.46-2.13.47-.9 1.22-1.39.74-.49 1.61-.49.67 0 1.16.23.48.23.98.65l-.07-1.3v-2.92h1.29v11.14h-1.05l-.11-.9h-.04q-.45.45-1.04.77-.59.31-1.27.31zM311.58 111.62q.53 0 1.01-.26.47-.25.93-.77V106.6q-.47-.44-.92-.62t-.92-.18q-.61 0-1.1.37-.5.37-.8 1.02t-.3 1.52q0 .91.25 1.57t.72 1t1.13.34zM322.9 112.7q-.79 0-1.27-.31-.48-.32-.68-.89-.2-.58-.2-1.33v-4.22h-1.14v-.96l1.21-.07.14-2.14h1.06v2.14h2.07v1.03h-2.07v4.26q0 .69.26 1.07.26.39.92.39.21 0 .45-.07.23-.06.42-.14l.25.96q-.32.11-.69.2-.36.08-.73.08zM328.63 112.7q-1.02 0-1.85-.47-.82-.48-1.31-1.37-.48-.89-.48-2.13q0-.94.28-1.68.28-.73.76-1.26.49-.52 1.1-.8.62-.27 1.26-.27.98 0 1.65.44.68.43 1.03 1.23.36.81.36 1.9q0 .21-.01.39-.02.19-.05.34h-5.12q.04.81.37 1.41.33.59.88.92.54.33 1.27.33.56 0 1.02-.16.45-.16.88-.44l.45.85q-.49.32-1.1.55-.62.22-1.39.22zM326.24 108.11h4.07q0-1.15-.5-1.76-.49-.61-1.39-.61-.53 0-1 .28t-.78.8q-.32.52-.4 1.29zM332.07 112.52l2.51-3.96-2.31-3.64h1.39l1.02 1.66q.17.33.36.64.18.32.38.64h.07q.15-.32.33-.64.17-.31.34-.64l.94-1.66h1.33l-2.31 3.76l2.51 3.84h-1.4l-1.12-1.78q-.2-.35-.4-.69-.21-.34-.43-.67h-.07q-.18.33-.37.67t-.4.69l-1.02 1.78zM342.1 112.7q-.8 0-1.28-.31-.47-.32-.67-.89-.21-.58-.21-1.33v-4.22h-1.13v-.96l1.2-.07.14-2.14h1.07v2.14h2.07v1.03h-2.07v4.26q0 .69.26 1.07.25.39.91.39.21 0 .45-.07.24-.06.42-.14l.25.96q-.32.11-.68.2-.37.08-.73.08zM164.24 129.5q-.92 0-1.73-.47-.82-.47-1.3-1.36-.48-.88-.48-2.14q0-1.28.48-2.17t1.3-1.36q.81-.48 1.73-.48.7 0 1.34.27.64.26 1.13.78t.77 1.26.28 1.7q0 1.26-.49 2.14-.49.89-1.29 1.36t-1.74.47zM164.24 128.44q.66 0 1.16-.37.49-.36.77-1.02t.28-1.52q0-.89-.28-1.54-.28-.66-.77-1.03-.5-.36-1.16-.36t-1.15.36q-.5.37-.77 1.03-.28.65-.28 1.54q0 .86.28 1.52.27.66.77 1.02.49.37 1.15.37zM171.31 129.32l-2.74-7.6h1.33l1.43 4.32q.18.56.35 1.13.18.57.35 1.11h.07q.18-.54.35-1.11.18-.57.35-1.13l1.44-4.32h1.26l-2.69 7.6zM179.95 129.5q-1.02 0-1.85-.47-.82-.48-1.31-1.37-.48-.89-.48-2.13q0-.94.28-1.68.28-.73.76-1.26.49-.52 1.1-.8.62-.27 1.26-.27.98 0 1.65.44.68.43 1.03 1.23.36.81.36 1.9q0 .21-.01.39-.02.19-.05.34h-5.12q.04.81.37 1.41.33.59.88.92.54.33 1.27.33.56 0 1.01-.16.46-.16.89-.44l.45.85q-.49.32-1.1.55-.62.22-1.39.22zM177.56 124.91h4.07q0-1.15-.5-1.76-.49-.61-1.39-.61-.53 0-1 .28t-.79.8q-.31.52-.39 1.29zM184.63 129.32v-7.6h1.05l.12 1.38h.03q.39-.72.96-1.15t1.2-.43q.26 0 .45.04.19.03.36.13l-.24 1.11q-.2-.06-.35-.1-.15-.03-.39-.03-.46 0-1 .4-.53.4-.91 1.36v4.89zM190.27 129.32V120.5q0-.77.24-1.33.23-.56.72-.87t1.25-.31q.35 0 .68.07t.59.17l-.28 1q-.42-.21-.85-.21-.55 0-.81.37-.27.38-.27 1.12v8.81zM189.23 122.75v-.96l1.09-.07h2.83v1.03zM195.97 129.5q-.48 0-.78-.19-.3-.2-.44-.59-.14-.38-.14-.91v-9.63h1.29v9.71q0 .3.1.42.11.13.25.13.05 0 .11-.01.05-.01.17-.02l.16.98q-.12.04-.29.08-.17.03-.43.03zM201.55 129.5q-.92 0-1.73-.47-.82-.47-1.3-1.36-.48-.88-.48-2.14q0-1.28.48-2.17t1.3-1.36q.81-.48 1.73-.48.7 0 1.34.27.64.26 1.13.78t.77 1.26.28 1.7q0 1.26-.49 2.14-.49.89-1.29 1.36t-1.74.47zM201.55 128.44q.66 0 1.16-.37.49-.36.77-1.02t.28-1.52q0-.89-.28-1.54-.28-.66-.77-1.03-.5-.36-1.16-.36t-1.15.36q-.5.37-.77 1.03-.28.65-.28 1.54q0 .86.28 1.52.27.66.77 1.02.49.37 1.15.37zM208.19 129.32l-2.12-7.6h1.31l1.13 4.39q.13.55.23 1.07.11.52.22 1.05h.07q.12-.53.24-1.05t.26-1.07l1.19-4.39h1.25l1.19 4.39q.14.55.27 1.07t.26 1.05h.07q.11-.53.22-1.05.12-.52.24-1.07l1.11-4.39h1.23l-2.06 7.6h-1.55l-1.09-4.1q-.14-.53-.27-1.07t-.25-1.12h-.07q-.13.58-.25 1.12-.12.55-.27 1.1l-1.08 4.07zM218.24 129.5q-.38 0-.65-.27t-.27-.69q0-.45.27-.72.27-.26.65-.26t.65.26q.27.27.27.72q0 .42-.27.69t-.65.27z" fill="#cbd5e1"/>
</g>
</g>
</g>
</g>
<g class="debug-overlay" opacity="0.4">
<rect x="0" y="0" width="420" height="180" fill="none" stroke="#38bdf8" stroke-width="1"/>
<rect x="18" y="30" width="128" height="120" fill="none" stroke="#38bdf8" stroke-width="1"/>
<rect x="160" y="48" width="230" height="26" fill="none" stroke="#38bdf8" stroke-width="1"/>
<rect x="160" y="48" width="156.16" height="26.4" fill="none" stroke="#22c55e" stroke-width="1" stroke-dasharray="4,2"/>
<rect x="162.22" y="53.43" width="153.01" height="21.17" fill="none" stroke="#ff0000" stroke-width="1"/>
<line x1="160" y1="69.56" x2="316.16" y2="69.56" stroke="#fbbf24" stroke-width="0.5"/>
<rect x="160" y="82" width="230" height="50" fill="none" stroke="#38bdf8" stroke-width="1"/>
<rect x="160" y="82" width="174.34" height="16.8" fill="none" stroke="#22c55e" stroke-width="1" stroke-dasharray="4,2"/>
<rect x="160" y="98.8" width="186.84" height="16.8" fill="none" stroke="#22c55e" stroke-width="1" stroke-dasharray="4,2"/>
<rect x="160" y="115.6" width="60.19" height="16.8" fill="none" stroke="#22c55e" stroke-width="1" stroke-dasharray="4,2"/>
<rect x="160.73" y="84.58" width="182.78" height="44.92" fill="none" stroke="#ff0000" stroke-width="1"/>
<line x1="160" y1="95.72" x2="334.34" y2="95.72" stroke="#fbbf24" stroke-width="0.5"/>
<line x1="160" y1="112.52" x2="346.84" y2="112.52" stroke="#fbbf24" stroke-width="0.5"/>
<line x1="160" y1="129.32" x2="220.19" y2="129.32" stroke="#fbbf24" stroke-width="0.5"/>
</g>
</svg>This uses the same WASM layout and IR path as normal rendering. It is useful for checking element bounds, nesting depth, overflow, and whether generated IDs are stable enough to target later.
Programmatic Inspection
Use inspectScene in Node.js tools, build scripts, or CI.
ts
import { inspectScene } from "@boundsvg/core";
const inspection = inspectScene(engine, vnode, { textPathMode: "merged" });
if (!inspection.nodeIds.valid) {
throw new Error("Duplicate boundsvg node IDs found");
}
console.table(
inspection.bboxes.map(({ nodeId, type, x, y, w, h, depth, drawIndex }) => ({
nodeId,
type,
x,
y,
w,
h,
depth,
drawIndex,
})),
);inspectScene() returns the layout tree, IR, textMap, handlerMap, nodeTypeMap, bbox list, recoverable warnings, and summary stats. It does not run a TypeScript-side text engine; it reads the result produced by the normal WASM render pipeline.
Diagnostic fields and ownership
FatalError and RecoverableError use severity-specific contracts. Fatal diagnostics require code and message; recoverable diagnostics additionally require a non-empty fallback and a closed stage. Optional nodeId and context fields are preserved across Node, browser, and Worker routes.
Construct diagnostics with an explicit options object:
ts
new FatalError("ASSET_INVALID", "Asset data is invalid", {
stage: "validate",
nodeId: "hero",
context: { assetKind: "image" },
});
new RecoverableError("ASSET_PLACEHOLDER", "Asset could not be decoded", {
fallback: "rendered a placeholder",
stage: "ir",
nodeId: "hero",
context: { assetKind: "image" },
});Do not place severity, code, message, fallback, stage, or nodeId at the root of context. They are reserved diagnostic fields. The old positional constructor form and severity-less serialized objects are not accepted.
Warnings are mutable inspection values, but independently owned consumers do not share an object or context identity. A warning callback may annotate its value without changing IR.warnings, a compiled scene, or another callback. Warning order follows production order: native WASM warnings first, followed by warnings from later TypeScript-owned phases. Duplicate events are retained.
Scene document structural failures
decodeSceneDocument(), fromSceneDocument(), direct Engine Scene inputs, CLI Scene input, and Worker Scene transport share one structural error family. Every failure is a FatalError at stage validate, has no node ID, and keeps the same code, message, and bounded context across those routes.
| Code | Message |
|---|---|
SCENE_DECODE_INVALID_VALUE | Scene document contains a value with an invalid structural type. |
SCENE_DECODE_MISSING_FIELD | Scene document is missing a required field. |
SCENE_DECODE_UNKNOWN_DISCRIMINANT | Scene document contains an unknown discriminant. |
SCENE_DECODE_UNKNOWN_KEY | Scene document contains an unsupported key. |
SCENE_DECODE_UNSAFE_VALUE | Scene document contains a value that is not a safe JSON data value. |
SCENE_DECODE_CYCLE | Scene document contains a cycle. |
SCENE_DECODE_RESOURCE_LIMIT | Scene document exceeds a decode resource limit. |
context.path is an RFC 6901 pointer (the root is an empty string). Other fields identify only the closed expected/actual category, missing field, discriminant, key, safety reason, first cycle path, or resource count. Paths are limited to 512 UTF-8 bytes and copied key or discriminant snippets to 96 UTF-8 bytes; truncation is reported explicitly. Rejected values, Proxy trap messages, stacks, and full requests are never copied into diagnostics.
Text layout fatal contract
Text layout failures use one structured contract across render and the six measurement methods: layoutTextFlow, layoutTextFlowWithExclusions, measureTextBlock, shrinkwrapText, shrinkwrapFlow, and measureIntrinsicInlineSize. Every diagnostic carries a closed operation name in context.operation; render uses renderTextLayout. Direct Engine calls, browser WASM, and Worker calls preserve the same code, message, stage, node ID, and context.
| Code | Fixed message | Stage |
|---|---|---|
TEXT_LAYOUT_INPUT_INVALID | Text layout request is invalid. | validate |
TEXT_FONT_UNAVAILABLE | No requested font is available for text layout. | text |
TEXT_LAYOUT_PREPARATION_FAILED | Text layout preparation failed. | text |
TEXT_FIT_INVALID_STEP | Text fit step is invalid. | text |
TEXT_FIT_PROBE_LIMIT | Text fit probe limit was exceeded. | text |
TEXT_ELLIPSIS_CANDIDATE_LIMIT | Text ellipsis candidate limit was exceeded. | text |
RICH_TEXT_MAX_DEPTH | Rich text depth limit was exceeded. | validate |
INLINE_RECT_COMPLEXITY_LIMIT | Inline rectangle limit was exceeded. | text |
TEXT_REGION_QUERY_INVALID | Text region query is invalid. | text |
TEXT_REGION_PROVIDER_FAILED | Text region provider failed. | text |
TEXT_FLOW_REGION_INVALID | Text flow region is invalid. | text |
TEXT_REGION_QUERY_LIMIT | Text region query limit was exceeded. | text |
TEXT_REGION_INTERVAL_LIMIT | Text region interval limit was exceeded. | text |
TEXT_LAYOUT_INVARIANT | Text layout invariant failed. | text |
TEXT_LAYOUT_OUTPUT_INVALID | Text layout transport returned an invalid result. | wasm |
TEXT_LAYOUT_PANIC | Text layout failed unexpectedly. | wasm |
TEXT_LAYOUT_WASM_FAILED | Text layout WASM transport failed. | wasm |
TEXT_LAYOUT_TRANSPORT_FAILED | Text layout transport failed. | engine |
TEXT_LAYOUT_RESULT_MISSING | Text layout result is missing required text data. | text |
TEXT_PATH_LAYOUT_UNAVAILABLE | Text-on-path layout is unavailable. | text |
Font parsing, outline extraction and shaping errors can also propagate through these layout operations. Their codes, fixed messages, stages and typed reason contexts are shared with the font backend diagnostic catalog: FONT_PARSE_FAILED, FONT_OUTLINE_FAILED, TEXT_SHAPING_FAILED, TEXT_SHAPING_LIMIT_EXCEEDED and TEXT_SHAPING_INVALID_OUTPUT.
TEXT_FONT_UNAVAILABLE has two precise forms. Layout preparation uses the text stage and the message in the table above, with effective-run and requested alias context. A lower-level native shaping or ellipsis call that cannot resolve its chain uses stage font, message No requested font is available., and reason: "unregisteredFont" with the requested weight. Propagating that native font error through a layout operation preserves the latter form. Normal Engine layout detects a missing chain during preparation first; callers must preserve the received message, stage and context rather than rewriting one form into the other.
Font availability is decided by the registered Rust font registry, not by a JavaScript alias precheck. The resolver keeps the authored family order, ignores empty and generic CSS family names as non-resolving candidates, and uses the first registered alias with the closest matching face. A missing primary or unused missing fallback does not fail when another requested alias resolves. If no requested alias resolves, TEXT_FONT_UNAVAILABLE identifies the first failing effective run with a bounded alias list in context.
A resolved font lacking a character is different from an unresolved font family. Plain-text measurement and shrinkwrap use fallback-capable layout; rendering reports the text engine's MISSING_GLYPH warning, including Unicode notation such as U+1F389 (🎉), with stage: "text" and fallback: "blank".
Recursive rich text accepts a container depth of 48 and rejects depth 49 before calling a custom producer or WASM. Measurement errors have no node ID; render errors include an authored node ID when one exists. Both use RICH_TEXT_MAX_DEPTH, stage validate, and context containing operation, actual, and limit.
Malformed output context reports a bounded protocolPath and a type descriptor such as object or string(length=N), never the rejected value. Raw input, font bytes, thrown values, panic payloads, and registry contents are not copied into messages or context.
Migration from earlier text-layout errors
| Earlier behavior or code | Current behavior or code |
|---|---|
Built-in render or measurement precheck returned FONT_ALIAS_NOT_REGISTERED | Rust registry resolution returns TEXT_FONT_UNAVAILABLE only if every requested alias fails |
Missing-font strings, TEXT_LAYOUT_FAILED, or TEXT_LAYOUT_INVALID | TEXT_FONT_UNAVAILABLE with run and bounded alias context |
TEXT_REGION_PROVIDER_INVALID | TEXT_REGION_QUERY_INVALID, TEXT_REGION_PROVIDER_FAILED, or TEXT_FLOW_REGION_INVALID |
Six measurement WASM_INVALID_*_OUTPUT codes | TEXT_LAYOUT_OUTPUT_INVALID with phase: "decode" and a safe descriptor |
Render preparation returned TEXT_NO_LAYOUT | The exact domain code, usually TEXT_LAYOUT_PREPARATION_FAILED or TEXT_FONT_UNAVAILABLE |
A custom render producer omitted required text layout and returned TEXT_NO_LAYOUT | TEXT_LAYOUT_RESULT_MISSING |
Text-on-path layout returned TEXT_NO_LAYOUT | TEXT_PATH_LAYOUT_UNAVAILABLE |
| A malformed WASM throw was exposed as a generic layout failure | TEXT_LAYOUT_WASM_FAILED |
| An unknown custom producer throw was exposed as a generic layout failure | TEXT_LAYOUT_TRANSPORT_FAILED |
Shape operation fatal contract
Shape rendering and the nine low-level operations use one fixed diagnostic catalog. Every error carries context.operation. Standalone operations do not invent a node ID; rendered Shape and Symbol nodes preserve their real nodeId and use the operation names renderShape and renderSymbol.
Boundary failures are distinct from geometry-domain failures:
| Code | Fixed message | Stage | Context detail |
|---|---|---|---|
SHAPE_INPUT_INVALID | Shape operation input is invalid. | validate | reason |
SHAPE_OUTPUT_INVALID | Shape operation returned invalid output. | wasm | phase, and safe decode descriptors |
SHAPE_PANIC | Shape operation failed unexpectedly. | wasm | operation only |
SHAPE_WASM_FAILED | Shape operation WASM transport failed. | wasm | operation only |
SHAPE_WASM_CAPABILITY_MISSING | Required shape WASM capability is unavailable. | wasm | operation only |
SHAPE_INPUT_INVALID uses only serializationFailed, malformedJson, or invalidRequestShape as its reason. SHAPE_OUTPUT_INVALID uses serialize when Rust cannot safely materialize output and decode when Core rejects an untrusted successful value. Decode context may contain bounded protocolPath and received descriptors; it never includes the rejected raw value. Generated non-finite numbers are serialize failures, not invalid input, and are not clamped.
The closed geometry-domain codes are:
| Code | Condition |
|---|---|
SHAPE_BOOLEAN_CHILD_COUNT | A boolean node has fewer than two children |
SHAPE_PATH_DATA_INVALID | SVG path data cannot be parsed |
SHAPE_PATH_COMMAND_UNSUPPORTED | Path data uses an unsupported command |
SHAPE_BOOLEAN_TOPOLOGY_FAILED | A closed boolean boundary cannot be rebuilt |
SHAPE_DUPLICATE_PART_ID | Two addressable parts use the same ID |
SHAPE_GEOMETRY_MAX_DEPTH | Authored or resolved geometry exceeds depth 48 |
SHAPE_PATH_MULTIPLE_SUBPATHS | Path measurement receives multiple subpaths |
SHAPE_PATH_ZERO_LENGTH | Path measurement receives a zero-length path |
SHAPE_PATH_COMPLEXITY_LIMIT | Path measurement exhausts its work limit |
SHAPE_PATH_OFFSET_GEOMETRY_INVALID | Offset geometry cannot be materialized |
SHAPE_PATH_OFFSET_SAMPLE_LIMIT | Offset sampling exhausts its work limit |
SHAPE_BOOLEAN_PAIR_LIMIT | Boolean evaluation exhausts its pair limit |
SHAPE_REGION_CLIP_INTERVAL_INVALID | A clip interval is not finite and increasing |
SHAPE_REGION_CLIP_NON_MONOTONIC | A clipped contour is not axis-monotonic |
Not every domain code is reachable from every operation. For example, renderShapeRegionSvg receives an evaluated region and does not evaluate a geometry tree. A strict custom-WASM boundary rejects a valid-looking error whose operation and code combination cannot occur.
Long duplicate IDs are represented only by a UTF-8-safe prefix and an omitted byte count. Panic payloads, stacks, input JSON, complete duplicate IDs, and serde details are not copied into the diagnostic. Worker, React, CLI, and Video routes preserve known Shape/Symbol diagnostics rather than replacing them with a generic observer error.
Migration from earlier shape errors
| Earlier behavior | Current behavior |
|---|---|
| A generic render-compilation failure | The exact geometry-domain code, with renderShape or renderSymbol |
| Route-specific missing-capability codes | SHAPE_WASM_CAPABILITY_MISSING with the low-level operation |
| Route-specific invalid-result codes | SHAPE_OUTPUT_INVALID with phase: "decode" |
| A malformed thrown value exposed transport details | SHAPE_WASM_FAILED |
A non-finite derived number appeared as null, inf, or text | SHAPE_OUTPUT_INVALID with phase: "serialize" |
| A duplicate part ID was rejected by a TypeScript tree walk | Rust reports SHAPE_DUPLICATE_PART_ID while compiling the addressed geometry |
React Overlay
Use @boundsvg/react/inspect for structured state and @boundsvg/react/debug for its human-facing presentation.
tsx
import { BoundSvg } from "@boundsvg/react";
import {
BoundSvgDebugOverlay,
NodeInspectorPanel,
} from "@boundsvg/react/debug";
import { useBoundSvgInspection } from "@boundsvg/react/inspect";
function PreviewInspector({ vnode, selectedNodeId }) {
const { inspection, error, isReady } = useBoundSvgInspection(vnode);
if (error) {
return <p>{error.message}</p>;
}
return (
<div style={{ position: "relative", width: 420 }}>
<BoundSvg vnode={vnode} />
{isReady && (
<BoundSvgDebugOverlay
inspection={inspection}
labelMode="summary"
selectedNodeId={selectedNodeId}
highlightedBBoxes={[
{
id: "export",
label: "export area",
x: 20,
y: 24,
w: 240,
h: 160,
},
]}
/>
)}
<NodeInspectorPanel
inspection={inspection}
selectedNodeId={selectedNodeId}
/>
</div>
);
}The overlay is intentionally presentation-light. Style the wrapper and panel in your application, use filter to show only text nodes, interactive nodes, or a selected branch, and pass highlightedBBoxes when an editor needs to mark a crop box, hovered render-tree node, or custom validation region. The overlay keeps pointer-events: none, so selection and hover state should be controlled by your surrounding UI.
Diagnosing remaining WASM_INVALID_* errors
A remaining WASM_INVALID_* FatalError means the JavaScript package could not accept data returned by a WASM operation outside the text-layout and shape families. Malformed JSON can fail before a path or value is available.
Treat this as a bridge compatibility or implementation problem, not as a recoverable scene warning:
- Confirm that
@boundsvg/coreand the loaded boundsvg WASM artifact come from matching package versions. This includes copied or bundledwasm-pkgfiles. - Rebuild the WASM artifact and the package or application that embeds it so an older generated module is not retained in the output or cache.
- If the matching, freshly built pair still fails, report a boundsvg bug with the error code, message,
stage,protocolPath, andreceivedcontext. Include the render method and the smallest scene that reproduces it.
The six text measurement routes no longer use route-specific WASM_INVALID_*_OUTPUT codes. Use TEXT_LAYOUT_OUTPUT_INVALID and its operation, phase, protocolPath, and received context instead. Shape operations likewise use SHAPE_OUTPUT_INVALID rather than route-specific invalid-output codes.
CLI Reports
Use CLI diagnostics when assets come from SVG files or .scene.json files.
bash
boundsvg inspect \
--input card.svg \
--default-font NotoSansJP \
--font NotoSansJP:400:normal:./fonts/NotoSansJP-Regular.ttf
boundsvg export \
--input card.scene.json \
--font NotoSansJP:400:normal:./fonts/NotoSansJP-Regular.ttf \
--report card.report.json
boundsvg doctor \
--font NotoSansJP:400:normal:./fonts/NotoSansJP-Regular.ttfinspectprints render stats, node ID status, warnings, missing glyph counts, overflow counts, bboxes, and draw order.export --inspectprints the same JSON report to stderr while still writing the rendered output.export --report <file>writes the JSON report for CI artifacts.doctorchecks Node WASM initialization, the font registrations passed on the command line, and whether an ffmpeg is available for MP4 export.