Skip to content

fix: isolate goober pragma from host app to prevent react-hot-toast crash - #630

Merged
hitesh-shetty-cstk merged 1 commit into
develop_v4from
fix/goober-shared-instance-react19-crash
Jul 29, 2026
Merged

fix: isolate goober pragma from host app to prevent react-hot-toast crash#630
hitesh-shetty-cstk merged 1 commit into
develop_v4from
fix/goober-shared-instance-react19-crash

Conversation

@hitesh-shetty-cstk

Copy link
Copy Markdown
Contributor

What

Visual Builder called goober's setup(h) with Preact's h during init. setup() sets goober's global, shared element pragma. Because goober is a singleton hoisted across the host app's dependency tree, this flips the pragma for every goober consumer in the page, not just the SDK.

A host app that pairs the SDK with a goober-backed UI library such as react-hot-toast then renders through that Preact pragma. On React 19 the emitted elements carry the legacy element brand and React rejects them:

A React Element from an older version of React was rendered. This is not supported.

The result is a white screen the moment a toast (or any goober styled component) mounts, only inside Live Preview / Visual Builder.

Fix

Remove the setup(h) call and its now-unused setup / h imports.

The SDK only uses goober's css, glob, and keyframes, none of which read the pragma. It never uses styled, the sole consumer of the pragma. So setup(h) did nothing for the SDK's own styling and only leaked Preact's h into the host's shared goober instance. Removing it restores the pragma-free behavior the SDK used before this call was added, and stops the SDK from touching host-app goober state at all.

Why it is safe

  • No styled usage anywhere in the SDK source (the only API that needs the pragma).
  • css / glob / keyframes compute class names and inject sheets without the pragma.
  • No extractCss usage; no css() called with a function argument (the only path that reads context props).
  • The style functions the SDK does use worked without setup before this call existed.

Testing

  • Reproduced the crash in a standalone Next.js 15 + React 19 + react-hot-toast app (single hoisted goober), then confirmed the built change makes the crash disappear. A pragma probe shows the goober element brand stays on React 19's Symbol(react.transitional.element) before and after SDK init, instead of flipping to Symbol(react.element).
  • npm run build passes.
  • Full Visual Builder, edit-button, and timeline test suites pass (106 tests), including hover/overlay tests that render field outlines and cursors via goober css, confirming styling still works.

🤖 Generated with Claude Code

…rash

VisualBuilder called goober's setup(h) with Preact's h at init, which
mutates goober's shared global pragma. A host app that also uses a
goober-backed library such as react-hot-toast then renders through that
pragma, emitting Preact elements into a React 19 tree and crashing with
"A React Element from an older version of React was rendered."

The SDK only uses goober's css/glob/keyframes, none of which read the
pragma, and never uses styled (the sole pragma consumer). setup(h) was
therefore inert for the SDK and only leaked into the host. Removing it
restores the pragma-free behavior the SDK shipped with before the call
was introduced.

Co-Authored-By: Claude <noreply@anthropic.com>
@hitesh-shetty-cstk
hitesh-shetty-cstk requested review from a team as code owners July 29, 2026 09:46
@github-actions

Copy link
Copy Markdown

🔒 Security Scan Results

ℹ️ Note: Only vulnerabilities with available fixes (upgrades or patches) are counted toward thresholds.

Check Type Count (with fixes) Without fixes Threshold Result
🔴 Critical Severity 0 0 10 ✅ Passed
🟠 High Severity 0 0 25 ✅ Passed
🟡 Medium Severity 0 0 500 ✅ Passed
🔵 Low Severity 1 0 1000 ✅ Passed

⏱️ SLA Breach Summary

✅ No SLA breaches detected. All vulnerabilities are within acceptable time thresholds.

Severity Breaches (with fixes) Breaches (no fixes) SLA Threshold (with/no fixes) Status
🔴 Critical 0 0 15 / 30 days ✅ Passed
🟠 High 0 0 30 / 120 days ✅ Passed
🟡 Medium 0 0 90 / 365 days ✅ Passed
🔵 Low 0 0 180 / 365 days ✅ Passed

✅ BUILD PASSED - All security checks passed

@github-actions

github-actions Bot commented Jul 29, 2026

Copy link
Copy Markdown

Coverage Report

Status Category Percentage Covered / Total
🔵 Lines 67.35% 2523 / 3746
🔵 Statements 66.23% 2564 / 3871
🔵 Functions 64.56% 450 / 697
🔵 Branches 61.96% 1533 / 2474
File Coverage
File Stmts Branches Functions Lines Uncovered Lines
Changed Files
src/visualBuilder/index.ts 53.03% 26.76% 31.25% 53.03% 111-114, 119-128, 134-204, 212-245, 255-276, 330-332, 336, 390-393, 101-107
Generated in workflow #876 for commit e44b9e5 by the Vitest Coverage Report Action

@kirtesh-cstk kirtesh-cstk left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@github-actions

Copy link
Copy Markdown

🔒 Security Scan Results

ℹ️ Note: Only vulnerabilities with available fixes (upgrades or patches) are counted toward thresholds.

Check Type Count (with fixes) Without fixes Threshold Result
🔴 Critical Severity 0 0 10 ✅ Passed
🟠 High Severity 0 0 25 ✅ Passed
🟡 Medium Severity 0 0 500 ✅ Passed
🔵 Low Severity 0 0 1000 ✅ Passed

⏱️ SLA Breach Summary

✅ No SLA breaches detected. All vulnerabilities are within acceptable time thresholds.

Severity Breaches (with fixes) Breaches (no fixes) SLA Threshold (with/no fixes) Status
🔴 Critical 0 0 15 / 30 days ✅ Passed
🟠 High 0 0 30 / 120 days ✅ Passed
🟡 Medium 0 0 90 / 365 days ✅ Passed
🔵 Low 0 0 180 / 365 days ✅ Passed

✅ BUILD PASSED - All security checks passed

@hitesh-shetty-cstk
hitesh-shetty-cstk force-pushed the fix/goober-shared-instance-react19-crash branch from 041c500 to e44b9e5 Compare July 29, 2026 10:19
@github-actions

Copy link
Copy Markdown

🔒 Security Scan Results

ℹ️ Note: Only vulnerabilities with available fixes (upgrades or patches) are counted toward thresholds.

Check Type Count (with fixes) Without fixes Threshold Result
🔴 Critical Severity 0 0 10 ✅ Passed
🟠 High Severity 0 0 25 ✅ Passed
🟡 Medium Severity 0 0 500 ✅ Passed
🔵 Low Severity 0 0 1000 ✅ Passed

⏱️ SLA Breach Summary

✅ No SLA breaches detected. All vulnerabilities are within acceptable time thresholds.

Severity Breaches (with fixes) Breaches (no fixes) SLA Threshold (with/no fixes) Status
🔴 Critical 0 0 15 / 30 days ✅ Passed
🟠 High 0 0 30 / 120 days ✅ Passed
🟡 Medium 0 0 90 / 365 days ✅ Passed
🔵 Low 0 0 180 / 365 days ✅ Passed

✅ BUILD PASSED - All security checks passed

@hitesh-shetty-cstk
hitesh-shetty-cstk merged commit c173ba7 into develop_v4 Jul 29, 2026
14 checks passed
@hitesh-shetty-cstk
hitesh-shetty-cstk deleted the fix/goober-shared-instance-react19-crash branch July 29, 2026 10:20
This was referenced Aug 5, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants