Codex stop-hook on the prior per-node try/catch caught a leak: the catch logged but didn't roll back canvas state. drawNode pushes canvas.save() once per ancestor clipStack entry (node-renderer.ts:548) plus more for rotation / flip (574, 583) and per-shape sub-paths (701, 1094, 1102). If drawNode throws mid-loop, every save() between its entry and the throw stays on the stack — the next node's draw operates inside a leaked clip / leaked transform, and the canvas either renders nothing or renders to the wrong region. Snapshot canvas.getSaveCount() before each drawNode call; on catch, canvas.restoreToCount(saveCount) pops everything back to the baseline. Wrap the restoreToCount itself in a no-op catch since it can throw if the snapshot count is somehow above the current depth (shouldn't happen but guarded so the error reporter still runs). Net effect: per-node failures are now genuinely isolated. The canvas state at the start of each iteration is identical to where the previous iteration left it; one bad node can't smear its leaked state across the rest of the frame. |
||
|---|---|---|
| .. | ||
| agent-native@22f20e42cd | ||
| pen-acp | ||
| pen-ai-skills | ||
| pen-core | ||
| pen-engine | ||
| pen-figma | ||
| pen-mcp | ||
| pen-react | ||
| pen-renderer | ||
| pen-sdk | ||
| pen-types | ||
| CLAUDE.md | ||