fix(refig): REST API JSON without geometry=paths causes 0x0 raster surface panic (#585)#591
Conversation
…rface panic Root cause of #585: The Figma REST API GET /v1/files/:key response omits `size` and `relativeTransform` from every node when `geometry=paths` is not passed as a query param. The io-figma `positioning_trait` helper fell back to 0 for both width and height, producing 0x0 node dimensions. This caused `Backend::new_from_raster(0, 0)` to call `skia_safe::surfaces::raster_n32_premul((0, 0))` which returns `None` and the `.expect()` panicked with 'Failed to create raster surface'. Fixes: 1. packages/grida-canvas-io-figma/lib.ts — positioning_trait now accepts an optional parent node and falls back to absoluteBoundingBox for dimensions when size is absent, and computes relative insets from child/parent absolute bounding boxes when relativeTransform is absent. All node type handlers (FRAME, RECTANGLE, ELLIPSE, GROUP, SECTION, BOOLEAN_OPERATION, LINE, VECTOR, X_VECTOR, X_STAR, X_REGULAR_POLYGON) pass parent to positioning_trait. TEXT node likewise uses absoluteBoundingBox as fallback for size and position. 2. crates/grida-canvas/src/export/{export_as_image,export_as_svg,export_as_pdf}.rs — Added defensive guards that return None before calling Backend::new_from_raster when pixel dimensions are <= 0, preventing the panic in any future edge cases. Co-authored-by: Universe <universe@grida.co>
|
Cursor Agent can help with this pull request. Just |
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Caution Review failedPull request was closed or merged during review No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (6)
WalkthroughThe PR addresses issue Changes
Sequence Diagram(s)sequenceDiagram
actor REST as REST API Response
participant IO as Figma IO Factory
participant EXP as Export Functions
participant RAS as Raster Backend
REST->>IO: Document with absoluteBoundingBox<br/>(no size/relativeTransform)
IO->>IO: positioning_trait(node, parent)
IO->>IO: Derive dimensions from<br/>absoluteBoundingBox
IO->>IO: Compute insets from<br/>parent context
IO->>EXP: Positioned Grida node
EXP->>EXP: Validate pixel dimensions<br/>(pixel_w, pixel_h > 0)
alt Dimensions valid
EXP->>RAS: Create raster backend
RAS->>RAS: Generate output (PNG/PDF/SVG)
else Dimensions invalid
EXP->>EXP: Return None
end
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Suggested labels
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 4bb99a71fa
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| const szx = node.size?.x ?? absBox?.width ?? 0; | ||
| const szy = node.size?.y ?? absBox?.height ?? 0; |
There was a problem hiding this comment.
Recover local dimensions before reapplying node rotation
When a REST node is fetched without geometry=paths but still carries a non-zero rotation, absoluteBoundingBox.width/height are the post-rotation axis-aligned bounds, not the node's local size. Writing those values straight into layout_target_width/height means the importer later feeds the AABB back into AffineTransform::from_box_center(..., width, height, rotation), effectively rotating the node twice. A 100×50 rectangle rotated 90° will import as a 50×100 local rect plus 90° rotation, so rotated FRAME/RECTANGLE/ELLIPSE/etc. render with the wrong size and placement in no-geometry REST documents.
Useful? React with 👍 / 👎.
| layout_target_width: node.size?.x ?? lineAbsBox?.width ?? 0, | ||
| layout_target_height: 0, |
There was a problem hiding this comment.
Preserve line length in the no-geometry LINE fallback
For LINE nodes, absoluteBoundingBox.width is only the axis-aligned bbox width, not the segment length. The new fallback still hardcodes layout_target_height: 0, so a vertical or diagonal line fetched without geometry=paths collapses to roughly its stroke thickness once rotation is applied later. For example, a 100px vertical line with a 2px stroke will import as a 2px line instead of a 100px one.
Useful? React with 👍 / 👎.
Summary
Fixes #585 —
FigmaRenderer.render()panics with "Failed to create raster surface" when using a Figma REST API JSON fetched without thegeometry=pathsquery parameter.Root Cause
The Figma REST API
GET /v1/files/:keyresponse omitssizeandrelativeTransformfrom every node when thegeometry=pathsquery param is not included. OnlyabsoluteBoundingBoxis always present.The io-figma
positioning_traithelper fell back to0for both width and height whensizewas absent:This produced 0×0 node dimensions in the Grida IR, which flowed into:
Fixes
packages/grida-canvas-io-figma/lib.tspositioning_traitnow accepts an optionalparentargument and falls back toabsoluteBoundingBox.width/heightfor dimensions whensizeis absentchild.absoluteBoundingBox - parent.absoluteBoundingBoxwhenrelativeTransformis absentparenttopositioning_traitTEXTandLINEnode handlers use the same fallback patterncrates/grida-canvas/src/export/export_as_{image,svg,pdf}.rsNonebefore callingBackend::new_from_rasterwhen pixel dimensions are<= 0, preventing panics from any future edge casesTests
packages/grida-canvas-io-figma/__tests__/iofigma.rest-api.no-geometry.test.ts— 7 new unit tests verifying dimension/position fallbackpackages/grida-canvas-sdk-render-figma/__tests__/refig.test.ts— 1 new integration test that renders the exact node structure from the reported file through WASM without panickingSummary by CodeRabbit
Bug Fixes
Tests