Skip to content

fix(wrangler): emit an error event for watch-mode rebuild failures - #14561

Merged
edmundhung merged 2 commits into
cloudflare:mainfrom
martijnwalraven:callboard/watch-rebuild-buildfailed
Jul 6, 2026
Merged

fix(wrangler): emit an error event for watch-mode rebuild failures#14561
edmundhung merged 2 commits into
cloudflare:mainfrom
martijnwalraven:callboard/watch-rebuild-buildfailed

Conversation

@martijnwalraven

@martijnwalraven martijnwalraven commented Jul 5, 2026

Copy link
Copy Markdown
Contributor

When unstable_startWorker runs in watch mode and a rebuild fails, the logBuildOutput esbuild plugin logs the failure and swallows it — no error event is dispatched, so programmatic consumers cannot observe that dev is now serving the previous bundle. Initial build failures, by contrast, route through the error path and surface as buildFailed on the DevEnv.

This threads an optional onRebuildError(errors, warnings) callback through logBuildOutput/runBuild; BundlerController provides it and routes rebuild failures through the same error path as initial-build failures, attaching the esbuild messages as the error cause. Terminal output is unchanged (the error path still logs via logBuildFailure), buildFailed now fires symmetrically, and recovery is unaffected (the next successful rebuild emits reloadComplete as before).


  • Tests
    • Tests included/updated (BundleController: rebuild failure emits the event; next good build recovers)
  • Public documentation
    • Documentation not necessary because: unstable_startWorker is an experimental API; a changeset is included.

🤖 Generated with Claude Code


Open in Devin Review

Initial build failures route through the BundlerController's error
event, so DevEnv logs them and emits `buildFailed` — but watch-mode
rebuild failures were only logged from the log-build-output esbuild
plugin and never became events, leaving startWorker consumers unable
to observe a broken rebuild (only initial builds and config parse
errors fired `buildFailed`).

The plugin gains an optional `onRebuildError` callback that takes
ownership of the failure (including its logging) when provided;
runBuild threads it, and the BundlerController routes rebuild failures
through emitErrorEvent with the esbuild messages as a BuildFailure-
shaped cause — DevEnv's existing handling then logs via
logBuildFailure exactly as before (no double-logging) and emits
`buildFailed` symmetrically with initial builds. Existing
logBuildOutput callers are unaffected.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@changeset-bot

changeset-bot Bot commented Jul 5, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 69e1bee

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

This PR includes changesets to release 3 packages
Name Type
wrangler 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

@workers-devprod
workers-devprod requested review from a team and edmundhung and removed request for a team July 5, 2026 08:43
@workers-devprod

workers-devprod commented Jul 5, 2026

Copy link
Copy Markdown
Contributor

Codeowners approval required for this PR:

  • ✅ @cloudflare/wrangler
Show detailed file reviewers

@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: No Issues Found

Devin Review analyzed this PR and found no bugs or issues to report.

Open in Devin Review

@pkg-pr-new

pkg-pr-new Bot commented Jul 6, 2026

Copy link
Copy Markdown
@cloudflare/autoconfig

npm i https://pkg.pr.new/@cloudflare/autoconfig@14561

create-cloudflare

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

@cloudflare/deploy-helpers

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

@cloudflare/kv-asset-handler

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

miniflare

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

@cloudflare/pages-shared

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

@cloudflare/unenv-preset

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

@cloudflare/vite-plugin

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

@cloudflare/vitest-pool-workers

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

@cloudflare/workers-auth

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

@cloudflare/workers-editor-shared

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

@cloudflare/workers-utils

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

wrangler

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

commit: 69e1bee

@edmundhung

Copy link
Copy Markdown
Member

The change makes sense to me. Rebuild failures should be observable like initial build failures.

What are you using unstable_startWorker for today?

For context, we are likely going to steer users toward createTestHarness (a new integration harness to be announced soon) for testing use cases, or Vite's createServer when they need a dev server. I don’t think it should block this fix, but it would be helpful to understand the use case this is unblocking.

@martijnwalraven

Copy link
Copy Markdown
Contributor Author

What are you using unstable_startWorker for today?

I've been building my own daemon that coordinates typecheck, lint, tests, and dev servers for a worktree, and turns output into compact, diffed, actionable evidence (e.g. answering "What diagnostics changed as a result of the latest edits?", "What errors occurred since the last dev server reload?"). It's mainly meant for agents, because it avoids having them run different tools and repeatedly bring raw output into the context to interpret.

For context, we are likely going to steer users toward createTestHarness (a new integration harness to be announced soon) for testing use cases, or Vite's createServer when they need a dev server. I don’t think it should block this fix, but it would be helpful to understand the use case this is unblocking.

For testing, we're already on @cloudflare/vitest-pool-workers, so createTestHarness is likely not a good match.

The Vite plugin may be able to replace unstable_startWorker for us. We've honestly not evaluated it closely enough. It seems most of what we need is there already: dev registry on by default, persistState, inspectorPort, auxiliaryWorkers, and eager re-evaluation on save via the module runner's full-reload path. What's concretely missing for us compared to how we use unstable_startWorker:

  1. A typed, subscribable error surface. Build/config failures and uncaught runtime exceptions reach a consumer only as logger text (customLogger, with workerd structured logs flattened into the logger) — no equivalent of DevEnv's events with structured causes (file/line).
  2. A recovery signal. Nothing announces a successful reload after a failure (DevEnv's reloadComplete), which a consumer needs to clear error state.
  3. (Minor) API-shaped control of the dev-registry path for ephemeral/isolated environments instead of through env variables like MINIFLARE_REGISTRY_PATH.

If those sound like additions that would be helpful to more people, I'm happy to take a stab at it and open a PR.

@edmundhung

Copy link
Copy Markdown
Member

I will need to discuss this with my team further. But the list looks reasonable to me.

I am gonna merge the PR first. Thanks for the fix!

@martijnwalraven

Copy link
Copy Markdown
Contributor Author

I will need to discuss this with my team further. But the list looks reasonable to me.

Thanks! Note that #14562 is related to this, but it's not as straightforward a fix, so it may need more scrutiny.

@workers-devprod workers-devprod 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.

Codeowners reviews satisfied

@github-project-automation github-project-automation Bot moved this from Untriaged to Approved in workers-sdk Jul 6, 2026
@edmundhung
edmundhung merged commit b973ed3 into cloudflare:main Jul 6, 2026
74 of 76 checks passed
@github-project-automation github-project-automation Bot moved this from Approved to Done in workers-sdk Jul 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

3 participants