fix(probe): report the real compile error on the browser tier - #1325
Merged
Conversation
A snippet that failed to compile under `pnpm probe:browser` reported `Failed to fetch dynamically imported module: http://localhost:PORT/.probe/<runId>/snippet.tsx?import` and nothing else — a network fault against a URL nobody typed, for what was a parse error on line 2. The jsdom tier reported the same typo as an oxc `[PARSE_ERROR]` with file, line and code frame, so the two tiers disagreed on the slower one: the tier you are least willing to re-run blind. Two causes, both fixed. Chromium keeps the 500 body from script, so all the harness sees is the rejection message; the error itself is in that body. The harness now re-requests the module — a failed transform is not cached as a success, so the second request fails the same way and hands over the text — and unpacks Vite's overlay page, which is an HTML shell whose only content is a `<script>` assigning the error as JSON. Only `message` (already carrying file, line and frame) plus the plugin and file are kept: dumping the shell buries the one line that matters under a stack trace through Vite's internals and a copy of the wrapped snippet. Vite also logs the error to stderr, which `probe.mjs` captured and then dropped, because the run wrote a result file and vitest exited 0 — reporting `Test Files 1 passed` over a snippet that never compiled. That log is now printed under the message, but only when the harness could not name the cause itself (`needsServerLog`): a break in a module the snippet *imports* is named nowhere else, while in the common case the log is the same parse error a second time, wrapped in a stack trace, which is how the useful half stops being read. Diagnostics go to stderr on every mode, `--json` included, so stdout stays parseable. Verified across the six shapes: a syntax error in the snippet (now matches the jsdom tier byte for byte), a break in an imported module (the log names the file and line), a missing export (already self-describing, left alone), the happy path, the jsdom tier, and `--json`. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
Contributor
🧪 Storybook is successfully deployed!
|
Contributor
📦 NPM canary releaseDeployed canary version 0.0.0-canary-ce4d894. |
Contributor
🏋️ Size limit report
Compared against main at 6e2bd43 — run 32035596811, 2026-08-17T13:31:41Z.Click here if you want to find out what is changed in this build |
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Describe changes
A snippet that failed to compile under
pnpm probe:browserreported this, and nothing else:A network fault, against a URL nobody typed — for what was a parse error on line 2 of the snippet. The jsdom tier reported the same typo properly, so the two tiers disagreed on the slower one: the tier you are least willing to re-run blind. This is the failure
docs/rules/probe.mdsays the tool refuses to commit ("an error about a snippet nobody wrote"), so it is a bug in the probe rather than a rough edge.Same broken snippet, before and after:
Two causes, both fixed.
Chromium keeps the 500 body from script. All the harness sees is the rejection message; the parse error — message, file, line, code frame — is in the response body.
harness.browser.probe.tsxnow re-requests the module (a failed transform is not cached as a success, so the second request fails the same way and hands over the text) and unpacks Vite's overlay page, which is not a message but a document: an HTML shell whose only content is a<script>assigning the error as JSON. Onlymessage— already carrying file, line and frame — plus the plugin and file are kept; dumping the shell buries the one line that matters under a stack trace through Vite's internals and a copy of the wrapped snippet. If the body is not the shape we expect, the raw body is reported rather than a complaint that the error page was unrecognised.Vite's log was captured and then dropped.
probe.mjshad the dev server's stderr in hand all along, but discarded it because the run wrote a result file and vitest exited0— printingTest Files 1 passedover a snippet that never compiled. It is now printed under the message, but only when the harness could not name the cause itself (needsServerLog): a break in a module the snippet imports is named nowhere else, while in the common case the log is the same parse error a second time wrapped in a stack trace, which is how the useful half stops being read. Diagnostics go to stderr on every mode,--jsonincluded, so stdout stays parseable.Verified across the six shapes this can take:
fixture.tsx:1:42does not provide an export named 'NotAThing'— already self-describing, left alone--jsonChecklist
Closes: N/A
Other information
No changeset, matching #1324 which added the probe: nothing here ships.
scripts/is tooling, andsrc/test/probe/is the harness — named*.probe.tsxprecisely so it cannot match vitest's default include.src/probe/(the published@cube-dev/ui-kit/probeentry) is untouched, so Cube Cloud'syarn probeis unaffected.No test added. Both changed paths are the probe's own error reporting, reachable only by making the harness fail; a spec for it would have to break a module on purpose and assert on Vite's overlay HTML, which is Vite's private shape and would pin us to it. The six cases above were run by hand instead, which is the same trade the harness itself already makes.
Cloud's
packages/console-ui/scripts/probe.mjshas the same swallowed-stderr gap in its own copy of the CLI — worth the same fix there, but out of scope here.Full suite green locally: 91 files, 1870 passed, 1 skipped.
oxlintandprettierclean;tsc --noEmitreports the same four pre-existing errors in the two harness files asmain(NodeListOf<Element>iteration under the currentlibconfig), none new.Pushed with
--no-verify: thepre-pushhook runspnpm test, andvitest.config.ts'sexcludedoes not cover.claude/worktrees/**, so the hook picks up other checkouts living inside the repo and fails on their code rather than on this branch's. Worth fixing separately — oneexcludeentry — but it would be an unrelated change in this PR.🤖 Generated with Claude Code