Skip to content

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 });
debug-bbox example
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.

CodeMessage
SCENE_DECODE_INVALID_VALUEScene document contains a value with an invalid structural type.
SCENE_DECODE_MISSING_FIELDScene document is missing a required field.
SCENE_DECODE_UNKNOWN_DISCRIMINANTScene document contains an unknown discriminant.
SCENE_DECODE_UNKNOWN_KEYScene document contains an unsupported key.
SCENE_DECODE_UNSAFE_VALUEScene document contains a value that is not a safe JSON data value.
SCENE_DECODE_CYCLEScene document contains a cycle.
SCENE_DECODE_RESOURCE_LIMITScene 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.

CodeFixed messageStage
TEXT_LAYOUT_INPUT_INVALIDText layout request is invalid.validate
TEXT_FONT_UNAVAILABLENo requested font is available for text layout.text
TEXT_LAYOUT_PREPARATION_FAILEDText layout preparation failed.text
TEXT_FIT_INVALID_STEPText fit step is invalid.text
TEXT_FIT_PROBE_LIMITText fit probe limit was exceeded.text
TEXT_ELLIPSIS_CANDIDATE_LIMITText ellipsis candidate limit was exceeded.text
RICH_TEXT_MAX_DEPTHRich text depth limit was exceeded.validate
INLINE_RECT_COMPLEXITY_LIMITInline rectangle limit was exceeded.text
TEXT_REGION_QUERY_INVALIDText region query is invalid.text
TEXT_REGION_PROVIDER_FAILEDText region provider failed.text
TEXT_FLOW_REGION_INVALIDText flow region is invalid.text
TEXT_REGION_QUERY_LIMITText region query limit was exceeded.text
TEXT_REGION_INTERVAL_LIMITText region interval limit was exceeded.text
TEXT_LAYOUT_INVARIANTText layout invariant failed.text
TEXT_LAYOUT_OUTPUT_INVALIDText layout transport returned an invalid result.wasm
TEXT_LAYOUT_PANICText layout failed unexpectedly.wasm
TEXT_LAYOUT_WASM_FAILEDText layout WASM transport failed.wasm
TEXT_LAYOUT_TRANSPORT_FAILEDText layout transport failed.engine
TEXT_LAYOUT_RESULT_MISSINGText layout result is missing required text data.text
TEXT_PATH_LAYOUT_UNAVAILABLEText-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 codeCurrent behavior or code
Built-in render or measurement precheck returned FONT_ALIAS_NOT_REGISTEREDRust registry resolution returns TEXT_FONT_UNAVAILABLE only if every requested alias fails
Missing-font strings, TEXT_LAYOUT_FAILED, or TEXT_LAYOUT_INVALIDTEXT_FONT_UNAVAILABLE with run and bounded alias context
TEXT_REGION_PROVIDER_INVALIDTEXT_REGION_QUERY_INVALID, TEXT_REGION_PROVIDER_FAILED, or TEXT_FLOW_REGION_INVALID
Six measurement WASM_INVALID_*_OUTPUT codesTEXT_LAYOUT_OUTPUT_INVALID with phase: "decode" and a safe descriptor
Render preparation returned TEXT_NO_LAYOUTThe exact domain code, usually TEXT_LAYOUT_PREPARATION_FAILED or TEXT_FONT_UNAVAILABLE
A custom render producer omitted required text layout and returned TEXT_NO_LAYOUTTEXT_LAYOUT_RESULT_MISSING
Text-on-path layout returned TEXT_NO_LAYOUTTEXT_PATH_LAYOUT_UNAVAILABLE
A malformed WASM throw was exposed as a generic layout failureTEXT_LAYOUT_WASM_FAILED
An unknown custom producer throw was exposed as a generic layout failureTEXT_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:

CodeFixed messageStageContext detail
SHAPE_INPUT_INVALIDShape operation input is invalid.validatereason
SHAPE_OUTPUT_INVALIDShape operation returned invalid output.wasmphase, and safe decode descriptors
SHAPE_PANICShape operation failed unexpectedly.wasmoperation only
SHAPE_WASM_FAILEDShape operation WASM transport failed.wasmoperation only
SHAPE_WASM_CAPABILITY_MISSINGRequired shape WASM capability is unavailable.wasmoperation 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:

CodeCondition
SHAPE_BOOLEAN_CHILD_COUNTA boolean node has fewer than two children
SHAPE_PATH_DATA_INVALIDSVG path data cannot be parsed
SHAPE_PATH_COMMAND_UNSUPPORTEDPath data uses an unsupported command
SHAPE_BOOLEAN_TOPOLOGY_FAILEDA closed boolean boundary cannot be rebuilt
SHAPE_DUPLICATE_PART_IDTwo addressable parts use the same ID
SHAPE_GEOMETRY_MAX_DEPTHAuthored or resolved geometry exceeds depth 48
SHAPE_PATH_MULTIPLE_SUBPATHSPath measurement receives multiple subpaths
SHAPE_PATH_ZERO_LENGTHPath measurement receives a zero-length path
SHAPE_PATH_COMPLEXITY_LIMITPath measurement exhausts its work limit
SHAPE_PATH_OFFSET_GEOMETRY_INVALIDOffset geometry cannot be materialized
SHAPE_PATH_OFFSET_SAMPLE_LIMITOffset sampling exhausts its work limit
SHAPE_BOOLEAN_PAIR_LIMITBoolean evaluation exhausts its pair limit
SHAPE_REGION_CLIP_INTERVAL_INVALIDA clip interval is not finite and increasing
SHAPE_REGION_CLIP_NON_MONOTONICA 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 behaviorCurrent behavior
A generic render-compilation failureThe exact geometry-domain code, with renderShape or renderSymbol
Route-specific missing-capability codesSHAPE_WASM_CAPABILITY_MISSING with the low-level operation
Route-specific invalid-result codesSHAPE_OUTPUT_INVALID with phase: "decode"
A malformed thrown value exposed transport detailsSHAPE_WASM_FAILED
A non-finite derived number appeared as null, inf, or textSHAPE_OUTPUT_INVALID with phase: "serialize"
A duplicate part ID was rejected by a TypeScript tree walkRust 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:

  1. Confirm that @boundsvg/core and the loaded boundsvg WASM artifact come from matching package versions. This includes copied or bundled wasm-pkg files.
  2. 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.
  3. If the matching, freshly built pair still fails, report a boundsvg bug with the error code, message, stage, protocolPath, and received context. 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.ttf
  • inspect prints render stats, node ID status, warnings, missing glyph counts, overflow counts, bboxes, and draw order.
  • export --inspect prints the same JSON report to stderr while still writing the rendered output.
  • export --report <file> writes the JSON report for CI artifacts.
  • doctor checks Node WASM initialization, the font registrations passed on the command line, and whether an ffmpeg is available for MP4 export.