fix(frontend): resolve the refractor chunk failure that remounts the playground and closes the Advanced drawer#5323
fix(frontend): resolve the refractor chunk failure that remounts the playground and closes the Advanced drawer#5323mmabrouk wants to merge 1 commit into
Conversation
…playground and closes the Advanced drawer The production webpack build stubbed out react-syntax-highlighter's dynamic import of refractor/all via an IgnorePlugin. When the agent chat markdown renderer (AgentChatSlice/assets/markdown.tsx, PrismAsync) highlighted a fenced code block, that ignored chunk threw "Cannot find module 'refractor/all'", tripping the Layout error boundary and remounting the playground subtree, which unmounted the open Advanced drawer. refractor@5 is installed and resolves every subpath rsh imports (all 297 languages plus /all and /core), so the ignore was stale and purely harmful. Remove it so the chunk loads. Claude-Session: https://claude.ai/code/session_01Hyn9365BLPXDmNZShrQkmH
|
@coderabbitai review |
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
📝 WalkthroughWalkthroughThe non-development Next.js Webpack configuration now ignores only ChangesWebpack import handling
Estimated code review effort: 2 (Simple) | ~5 minutes 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ 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 |
✅ Action performedReview finished.
|
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
web/oss/next.config.ts (1)
144-148: 📐 Maintainability & Code Quality | 🔵 TrivialConsider Turbopack compatibility for custom ignores.
While this
webpack.IgnorePluginconfiguration works correctly for Webpack builds, Next.js 15 (as of 15.4+) is stabilizing Turbopack as the production bundler (next build --turbopack). Custom Webpack plugins added tonext.config.tsare completely ignored by Turbopack. If the project eventually migrates to Turbopack, you will need to replace this plugin with Turbopack-compatible configurations (e.g., usingexperimental.turbo.resolveAliasor marking the module as external).
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: 7bc4b6cb-deb2-41cf-a2a0-2cefcdc7cd78
📒 Files selected for processing (1)
web/oss/next.config.ts
| // Ignore the mermaid import from @ant-design/x — we don't use that surface. | ||
| // NOTE: do not ignore `refractor/*` here. react-syntax-highlighter's PrismAsync | ||
| // dynamically imports `refractor/all` at runtime; stubbing it out throws | ||
| // "Cannot find module 'refractor/all'" when a chat code block renders, which trips | ||
| // the app error boundary and remounts the playground. refractor@5 resolves every | ||
| // subpath rsh imports, so the import must be left intact. |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win
Condense the inline comment to comply with guidelines.
The explanation is valid and highlights a genuinely surprising constraint, but it spans six lines. As per coding guidelines, keep in-code comments to one short line maximum unless a genuinely surprising constraint requires a brief exception. The comment can be significantly shortened while retaining the core warning about the runtime constraints.
♻️ Proposed fix
- // Ignore the mermaid import from `@ant-design/x` — we don't use that surface.
- // NOTE: do not ignore `refractor/*` here. react-syntax-highlighter's PrismAsync
- // dynamically imports `refractor/all` at runtime; stubbing it out throws
- // "Cannot find module 'refractor/all'" when a chat code block renders, which trips
- // the app error boundary and remounts the playground. refractor@5 resolves every
- // subpath rsh imports, so the import must be left intact.
+ // Ignore unused mermaid. Do not ignore `refractor/*`; react-syntax-highlighter requires it at runtime to prevent code block rendering crashes.📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| // Ignore the mermaid import from @ant-design/x — we don't use that surface. | |
| // NOTE: do not ignore `refractor/*` here. react-syntax-highlighter's PrismAsync | |
| // dynamically imports `refractor/all` at runtime; stubbing it out throws | |
| // "Cannot find module 'refractor/all'" when a chat code block renders, which trips | |
| // the app error boundary and remounts the playground. refractor@5 resolves every | |
| // subpath rsh imports, so the import must be left intact. | |
| // Ignore unused mermaid. Do not ignore `refractor/*`; react-syntax-highlighter requires it at runtime to prevent code block rendering crashes. |
Source: Coding guidelines
Railway Preview Environment
|
Symptom
In the agent playground, opening the Configuration panel's Advanced drawer and
clicking a section row ("Execution environment" or "Permissions") intermittently
(~1-in-4) closed the whole drawer instead of expanding the section. In one case the click
fell through the closing overlay and opened the Turn inspector for an off-screen chat turn.
Repro and evidence:
docs/design/agent-workflows/projects/qa/ui-exploration-20260714.md(bug 2).
Console evidence captured at every failure
[EXCEPTION] Error: Cannot find module 'refractor/all'from a lazy-loaded chunk,each time followed by a duplicate burst of app-boot console lines (organizations
fetches, atomFamily/loadable deprecation warnings) — the signature of a partial React
tree remount.
[WARNING] Detected store mutation during atom read(Jotai) — a separate anti-pattern,not the cause here (see follow-up below).
Root cause
web/oss/next.config.tsregistered a production-only webpackIgnorePlugin:It stubbed out every
refractor/*import made byreact-syntax-highlighter,including
refractor/all. The agent chat markdown renderer(
web/oss/src/components/AgentChatSlice/assets/markdown.tsx) highlights fenced codeblocks with
PrismAsync, which at runtime does a dynamicimport('refractor/all')to load languages on demand. With the import stubbed, thatlazy chunk threw
Cannot find module 'refractor/all'the first time a chat message witha code block rendered.
Causal chain (drawer close)
PrismAsyncdynamically importsrefractor/all.Cannot find module 'refractor/all'.web/oss/src/components/Layout/Layout.tsxwraps the page{children}in<ErrorBoundary>) catches it and remounts the playground subtree(the duplicate app-boot burst).
"closes" instead of the section expanding.
Why intermittent (~25%): the throw only fires when the visible chat content contains
a fenced code block whose language triggers PrismAsync's
refractor/allload. Turnswithout a code block never hit the broken chunk, so only some interactions repro.
Click fall-through: a consequence of the same remount — during the unmount window the
drawer overlay is gone, so the click lands on whatever is behind it (the off-screen Turn
inspector). No separate fix needed.
The plugin was stale:
refractor@5.0.0is installed and resolves every subpath rshimports — all 297 async languages plus
./alland./core(0 missing). The comment evenclaimed it was about "@ant-design/x that we don't use", but the refractor entry was scoped
to
react-syntax-highlighter, which the app does use.Fix
Remove the
refractorIgnorePlugin(keep the legitimatemermaidone for@ant-design/x). The dynamicrefractor/allchunk now resolves and loads, so noexception, no error-boundary remount, and the drawer stays open.
Before / after
refractor/all→ chat code block render throws →playground remounts → Advanced drawer closes on section click (~1-in-4).
refractor/allloads as a lazy chunk → code blocks highlight normally →no remount → drawer sections expand as expected.
web/ee/next.config.tsimports the OSS config, so this single change covers both editions.Verification
refractor@5.0.0exports./all,./core, and every one of the 297 languagesubpaths
react-syntax-highlighter@16.1.1async-imports (diffed the two package trees:zero missing).
builds (
!isDevelopment), matching the live repro on a deployed build and explaining whydev/turbopack never showed it.
pnpm build-oss(webpack production branch,NODE_ENV=production) with the plugin removed — exit 0, all 7 turbo tasks successful,no refractor/rsh resolution errors, so the plugin's original "prevent build errors"
motivation did not resurface. The emitted chunk
79590.*(the exact chunk number thatthrew
Cannot find module 'refractor/all'in the QA capture) now weighs ~380K andcontains the refractor language definitions instead of a stub.
prettier --writeon the touched file: unchanged.Manual verification (deployed build, per the findings doc): open an agent playground, send
a message that renders a fenced code block, then open the Advanced drawer and click
"Execution environment" / "Permissions" repeatedly through several open/close cycles. The
section should expand every time with no
Cannot find module 'refractor/all'exception andno drawer self-dismiss.
Follow-up (out of scope)
The Jotai
Detected store mutation during atom readwarning is a separate stateanti-pattern, not the cause of this remount. Left untouched here; worth a dedicated pass.
https://claude.ai/code/session_01Hyn9365BLPXDmNZShrQkmH