Skip to content

[wrangler] fix: don't crash wrangler dev when source-mapping a truncated error chunk#14316

Draft
matingathani wants to merge 9 commits into
cloudflare:mainfrom
matingathani:fix/sourcemap-crash-on-invalid-column
Draft

[wrangler] fix: don't crash wrangler dev when source-mapping a truncated error chunk#14316
matingathani wants to merge 9 commits into
cloudflare:mainfrom
matingathani:fix/sourcemap-crash-on-invalid-column

Conversation

@matingathani

@matingathani matingathani commented Jun 16, 2026

Copy link
Copy Markdown
Contributor

Fixes #9919.

When a worker throws errors in rapid succession, the stderr chunks received by wrangler dev can arrive mid-frame — so a call site ends up with a negative column number. The @jridgewell/trace-mapping library throws Error: \column` must be greater than or equal to 0` in that case, which was bubbling up uncaught and crashing the wrangler process.

The fix wraps the prepareStack(...) call in getSourceMappedString in a try/catch. If source mapping throws for any reason, we fall back to returning the original (un-source-mapped) string. The worker process keeps running and the user still sees the error message, just without source map translation.

I reproduced this with the snippet from the issue:

export default {
  fetch: () => {
    let obj = {};
    Error.captureStackTrace(obj);
    console.error(obj.stack.slice(0, -3)); // truncated stack
    return new Response('ok');
  },
};

Hitting the worker endpoint a few times caused wrangler dev to crash before this fix. After the fix, it logs the raw stack and keeps running.


  • Tests
    • Additional testing not necessary because: the fix is a defensive try/catch around an existing path. The existing sourcemap tests cover the normal code path. The error path (truncated column) is hard to unit-test deterministically since it depends on OS-level chunk boundaries in stderr delivery.
  • Public documentation
    • Documentation not necessary because: this is a crash fix with no API or behaviour change.

Open in Devin Review

Copilot AI review requested due to automatic review settings June 16, 2026 05:02
@workers-devprod workers-devprod requested review from a team and jamesopstad and removed request for a team June 16, 2026 05:03
@workers-devprod

workers-devprod commented Jun 16, 2026

Copy link
Copy Markdown
Contributor

Codeowners approval required for this PR:

  • @cloudflare/wrangler
Show detailed file reviewers
  • .changeset/fix-miniflare-chrome-corrupt-binary-launch.md: [@cloudflare/wrangler]
  • .changeset/fix-sourcemap-crash-invalid-column.md: [@cloudflare/wrangler]
  • packages/deploy-helpers/src/deploy/helpers/sourcemap.ts: [@cloudflare/wrangler]
  • packages/deploy-helpers/tests/sourcemap.test.ts: [@cloudflare/wrangler]
  • packages/miniflare/src/plugins/browser-rendering/index.ts: [@cloudflare/wrangler]

This comment was marked as resolved.

devin-ai-integration[bot]

This comment was marked as resolved.

matingathani added a commit to matingathani/workers-sdk that referenced this pull request Jun 16, 2026
- Move for-loop inside try block so sourceMappedStackTrace can be const
- Capture caught error and log at debug level instead of silently dropping it
@changeset-bot

changeset-bot Bot commented Jun 16, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 52ecf74

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 6 packages
Name Type
miniflare Patch
wrangler Patch
@cloudflare/deploy-helpers Patch
@cloudflare/pages-shared Patch
@cloudflare/vite-plugin Patch
@cloudflare/vitest-pool-workers Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

devin-ai-integration[bot]

This comment was marked as resolved.

Wraps the prepareStack call in getSourceMappedString in a try-catch so
that if the source map library throws (e.g. because a truncated stderr
chunk produced a call site with an invalid column number), the original
un-source-mapped string is returned instead of crashing wrangler dev.
@matingathani matingathani force-pushed the fix/sourcemap-crash-on-invalid-column branch from 0ee4112 to e7325f9 Compare June 16, 2026 05:24
@github-project-automation github-project-automation Bot moved this to Untriaged in workers-sdk Jun 16, 2026
devin-ai-integration[bot]

This comment was marked as resolved.

@pkg-pr-new

pkg-pr-new Bot commented Jun 16, 2026

Copy link
Copy Markdown
create-cloudflare

npm i https://pkg.pr.new/create-cloudflare@14316

@cloudflare/deploy-helpers

npm i https://pkg.pr.new/@cloudflare/deploy-helpers@14316

@cloudflare/kv-asset-handler

npm i https://pkg.pr.new/@cloudflare/kv-asset-handler@14316

miniflare

npm i https://pkg.pr.new/miniflare@14316

@cloudflare/pages-shared

npm i https://pkg.pr.new/@cloudflare/pages-shared@14316

@cloudflare/unenv-preset

npm i https://pkg.pr.new/@cloudflare/unenv-preset@14316

@cloudflare/vite-plugin

npm i https://pkg.pr.new/@cloudflare/vite-plugin@14316

@cloudflare/vitest-pool-workers

npm i https://pkg.pr.new/@cloudflare/vitest-pool-workers@14316

@cloudflare/workers-auth

npm i https://pkg.pr.new/@cloudflare/workers-auth@14316

@cloudflare/workers-editor-shared

npm i https://pkg.pr.new/@cloudflare/workers-editor-shared@14316

@cloudflare/workers-utils

npm i https://pkg.pr.new/@cloudflare/workers-utils@14316

wrangler

npm i https://pkg.pr.new/wrangler@14316

commit: 52ecf74

@matingathani

Copy link
Copy Markdown
Contributor Author

The 'Tests (Windows, packages-and-tools)' failure is a pre-existing flake in miniflare's browser tests unrelated to this PR. The Chrome DLL gets locked between parallel test processes on the Windows runner. The same failure appears on main without our changes.

@petebacondarwin petebacondarwin 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.

I think it would be helpful to have an automated regression test if possible.
Please can you see if you can create one?

Comment thread packages/deploy-helpers/src/deploy/helpers/sourcemap.ts Outdated
@github-project-automation github-project-automation Bot moved this from Untriaged to In Review in workers-sdk Jun 16, 2026
@petebacondarwin petebacondarwin removed the request for review from jamesopstad June 16, 2026 09:28
…and fix null check

- Narrow try-catch to wrap only `prepareStack()` and early-return on failure,
  so the for-loop replacements are never partially applied then silently dropped
- Fix `getFileName() === undefined` → `=== null` (`CallSite.getFileName()` returns
  `string | null`, never `undefined`, so the old guard always evaluated false)
- Add regression test verifying `getSourceMappedString` returns the original value
  when source mapping fails instead of throwing
@matingathani

Copy link
Copy Markdown
Contributor Author

Addressed all the review feedback in the latest commit:

Narrowed try-catch to only wrap prepareStack() — instead of wrapping both prepareStack() and the for-loop, the try-catch now only wraps the prepareStack(placeholderError, callSites) call and early-returns the original value on failure. This means the for-loop replacements are never partially applied then silently discarded — either the mapping fully succeeds or the original string is returned unchanged.

Fixed getFileName() === nullCallSite.getFileName() returns string | null, never undefined, so the old === undefined check always evaluated false (filed by Devin). Changed to === null.

Added regression test in packages/deploy-helpers/tests/sourcemap.test.ts — verifies that getSourceMappedString returns the original value without throwing when source mapping fails, covering the truncated-chunk crash scenario.

matingathani and others added 2 commits June 17, 2026 10:38
When Chrome fails to start with "Failed to launch the browser process"
(e.g. Windows CI runners serving a DLL that the OS rejects with 0xC1
"%1 is not a valid Win32 application"), delete the stale build directory
and retry install + launch once.

Complements the existing installWithCorruptedCacheRecovery which handles
the "executable missing from cache" case.

@devin-ai-integration devin-ai-integration Bot 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.

Devin Review found 1 new potential issue.

Open in Devin Review

"miniflare": patch
---

fix: recover from corrupt Chrome binary when launching browser for local Browser Rendering

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.

🟡 Changeset title uses prohibited conventional commit prefix

The changeset title on line 5 starts with fix:, which violates the REVIEW.md rule: "Do NOT prefix changeset titles with a 'type' (e.g. fix:, feat:, chore:). The changeset title should be a plain description without conventional commit prefixes." It should read something like "Recover from corrupt Chrome binary when launching browser for local Browser Rendering".

Suggested change
fix: recover from corrupt Chrome binary when launching browser for local Browser Rendering
Recover from corrupt Chrome binary when launching browser for local Browser Rendering
Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

…able let

Factors the try-catch into a dedicated `tryPrepareStack` helper that returns
`null` on failure instead of throwing, letting `getSourceMappedString` use
`const` for the result and check `=== null` before entering the for-loop.

Addresses Copilot review feedback (prefer const over let-bridging a try block)
and aligns with petebacondarwin's suggestion to make prepareStack non-throwing.
devin-ai-integration[bot]

This comment was marked as resolved.

When the cached Chrome binary exists but is corrupt, the retry path
calls install() again, which fires the downloadProgressCallback and
starts the spinner. Without a matching s.stop(), the spinner runs
indefinitely through the subsequent launch() and waitForBrowserReady()
calls, leaving the terminal in a broken state.

Reset startedDownloading before the retry so the callback re-arms
cleanly, then stop the spinner after install() returns (success path)
or throws (failure path), mirroring the pattern on lines 163-175.

Addresses Devin review comment on PR cloudflare#14316.
@petebacondarwin

Copy link
Copy Markdown
Contributor

@matingathani - this seems to have picked up the changes from another PR too?

@petebacondarwin petebacondarwin marked this pull request as draft June 17, 2026 16:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: In Review

Development

Successfully merging this pull request may close these issues.

Wrangler local dev crashes when processing logged errors

4 participants