wrangler
4.151.3 · 20 Oct 2026MIT OR Apache-2.018.1M / weekRepositoryHomepagenpmAtom feed
541 stable releases, newest first, by release line. Notes are quoted as the maintainers published them.
4.151.3
20 Oct 2026Allow
wrangler devto start module Workers without a default exportPreviously,
wrangler devfailed to start module Workers that exported only named entrypoints, such as RPC services, unless an unused default export was added. These Workers now start normally in local development without that workaround.Fetch the remote config diff from the configured compliance region
When a Worker was last deployed from the dashboard,
wrangler deployandwrangler versions uploaddownload its remote configuration to compare with the local one. These requests ignored thecompliance_regionfield in the Wrangler configuration file and only honoured theCLOUDFLARE_COMPLIANCE_REGIONenvironment variable. A FedRAMP High Worker configured through the config file would send them toapi.cloudflare.cominstead ofapi.fed.cloudflare.com, and the deploy would fail with authentication errors. They now use the same compliance region as the rest of the deploy.Fail with an error instead of hanging when local dev requests can't work under Bun
Bun's
fetch()ignores the undicidispatcherthat Miniflare routes requests through (oven-sh/bun#39247). Under Bun,createTestHarness()'sserver.fetch()andserver.getWorker()'sfetch(),email()andscheduled()now throw aUserError, requests to the dev server URL get a 503 naming the cause, and starting remote bindings throws aUserError. Each of these used to hang with no error.server.getWorker().getEnv()andgetExport()keep working under Bun.
Patch Changes
Allow
wrangler devto start module Workers without a default exportPreviously,
wrangler devfailed to start module Workers that exported only named entrypoints, such as RPC services, unless an unused default export was added. These Workers now start normally in local development without that workaround.Fetch the remote config diff from the configured compliance region
When a Worker was last deployed from the dashboard,
wrangler deployandwrangler versions uploaddownload its remote configuration to compare with the local one. These requests ignored thecompliance_regionfield in the Wrangler configuration file and only honoured theCLOUDFLARE_COMPLIANCE_REGIONenvironment variable. A FedRAMP High Worker configured through the config file would send them toapi.cloudflare.cominstead ofapi.fed.cloudflare.com, and the deploy would fail with authentication errors. They now use the same compliance region as the rest of the deploy.Fail with an error instead of hanging when local dev requests can't work under Bun
Bun's
fetch()ignores the undicidispatcherthat Miniflare routes requests through (oven-sh/bun#39247). Under Bun,createTestHarness()'sserver.fetch()andserver.getWorker()'sfetch(),email()andscheduled()now throw aUserError, requests to the dev server URL get a 503 naming the cause, and starting remote bindings throws aUserError. Each of these used to hang with no error.server.getWorker().getEnv()andgetExport()keep working under Bun.Stop
--strictdeploys and version uploads from aborting when the API omits optional binding fieldsPreviously,
wrangler deploy --strictandwrangler versions upload --strictcould report a destructive change for an unchanged configuration, for example an R2 bucket in the default jurisdiction, because a field the API left out was compared as removed. Missing and unset optional fields are now treated as equal, so these commands proceed when the local configuration matches the deployed Worker.
4.151.2
19 Oct 2026Only updates a dependency:miniflare 5.20261019.0-beta
4.151.1
16 Oct 2026Keep remote dev sessions alive through transient network failures
wrangler dev --remoteandgetPlatformProxy()refresh their preview token before it expires, but a single failed refresh — for example while the network was briefly down — stopped refreshing for good, leaving the session broken until restart. A failed refresh now retries every minute until it succeeds. Rebuilds also no longer push the refresh past the session's expiry.Fix
wrangler rollbackreporting success after the changed secrets confirmation is declinedPreviously, declining the "The following secrets have changed…" confirmation printed "Aborting rollback..." and then also printed a success message and the target version as the "Current Version ID", even though no deployment was made and the original version was still live. Wrangler now stops after aborting, so the output matches what is actually deployed.
Hide the
wrangler devhotkey bar when Turborepo does not forward input
Patch Changes
Keep remote dev sessions alive through transient network failures
wrangler dev --remoteandgetPlatformProxy()refresh their preview token before it expires, but a single failed refresh — for example while the network was briefly down — stopped refreshing for good, leaving the session broken until restart. A failed refresh now retries every minute until it succeeds. Rebuilds also no longer push the refresh past the session's expiry.Fix
wrangler rollbackreporting success after the changed secrets confirmation is declinedPreviously, declining the "The following secrets have changed…" confirmation printed "Aborting rollback..." and then also printed a success message and the target version as the "Current Version ID", even though no deployment was made and the original version was still live. Wrangler now stops after aborting, so the output matches what is actually deployed.
Hide the
wrangler devhotkey bar when Turborepo does not forward input
4.151.0
14 Oct 2026Include source maps by default in
wrangler build --experimental-cf-build-outputBuild Output now matches
wrangler deployandwrangler versions upload, which upload source maps by default, so Workers built for tools likecfget stack traces that point at the original source. Source maps that can't be resolved are skipped rather than failing the build. Setupload_source_maps = falseto opt out.Support local D1 queries through the experimental
d1_binding_jsrpccompatibility flagLocal D1 bindings now implement the RPC query backend used by
D1Database.query()and prepared-statement methods when the flag is enabled. Queries reuse local SQLite execution, including transactional batches, execution metadata, and session bookmarks, while bindings without the flag continue to use HTTP. Update the bundled workerd runtime to1.20261012.1and align the default compatibility date with that release.
Minor Changes
Include source maps by default in
wrangler build --experimental-cf-build-outputBuild Output now matches
wrangler deployandwrangler versions upload, which upload source maps by default, so Workers built for tools likecfget stack traces that point at the original source. Source maps that can't be resolved are skipped rather than failing the build. Setupload_source_maps = falseto opt out.
Patch Changes
Support local D1 queries through the experimental
d1_binding_jsrpccompatibility flagLocal D1 bindings now implement the RPC query backend used by
D1Database.query()and prepared-statement methods when the flag is enabled. Queries reuse local SQLite execution, including transactional batches, execution metadata, and session bookmarks, while bindings without the flag continue to use HTTP. Update the bundled workerd runtime to1.20261012.1and align the default compatibility date with that release.
4.150.0
13 Oct 2026Upload source maps by default for
wrangler deploy,wrangler versions uploadandwrangler previewWhen
upload_source_mapsisn't set in config or via--upload-source-maps, Wrangler now generates and uploads source maps so stack traces in logs andwrangler tailpoint at your original source without extra setup. In this default mode, source maps that can't be resolved (for example inlinedata:maps or missing.mapfiles from a custom build) are skipped rather than failing the upload. Settingupload_source_maps = truekeeps the existing strict behaviour, andupload_source_maps = false(or--no-upload-source-mapsfor deploy and versions upload) opts out.wrangler build --experimental-cf-build-outputis unchanged and still only includes source maps whenupload_source_maps = true.Stop
wrangler deploy,wrangler versions uploadandwrangler previewin projects that build for the Cloudflare CLI (cf)If your project builds through
cf, deploying it with Wrangler reads a different configuration, so it could update the wrong Worker or fail without explaining why. These commands now stop before uploading anything, name the.cloudflare/outputdirectory they found, and tell you to runcf deployinstead. If that directory is just left over from an earlier build, deleting it restores the Wrangler workflow.Ordinary Wrangler projects are unaffected, and
--dry-runstill works ondeployandversions upload. This is a new guard for the experimental Build Output Specification rather than a fix, and it gives three stable commands a failure mode they did not have before, so it is a minor.Clarify the Worker not found error during CI deploy validation
Wrangler now reports that the configured Worker could not be found in the account instead of incorrectly describing the failure as a name mismatch.
Minor Changes
Upload source maps by default for
wrangler deploy,wrangler versions uploadandwrangler previewWhen
upload_source_mapsisn't set in config or via--upload-source-maps, Wrangler now generates and uploads source maps so stack traces in logs andwrangler tailpoint at your original source without extra setup. In this default mode, source maps that can't be resolved (for example inlinedata:maps or missing.mapfiles from a custom build) are skipped rather than failing the upload. Settingupload_source_maps = truekeeps the existing strict behaviour, andupload_source_maps = false(or--no-upload-source-mapsfor deploy and versions upload) opts out.wrangler build --experimental-cf-build-outputis unchanged and still only includes source maps whenupload_source_maps = true.Stop
wrangler deploy,wrangler versions uploadandwrangler previewin projects that build for the Cloudflare CLI (cf)If your project builds through
cf, deploying it with Wrangler reads a different configuration, so it could update the wrong Worker or fail without explaining why. These commands now stop before uploading anything, name the.cloudflare/outputdirectory they found, and tell you to runcf deployinstead. If that directory is just left over from an earlier build, deleting it restores the Wrangler workflow.Ordinary Wrangler projects are unaffected, and
--dry-runstill works ondeployandversions upload. This is a new guard for the experimental Build Output Specification rather than a fix, and it gives three stable commands a failure mode they did not have before, so it is a minor.
Patch Changes
Clarify the Worker not found error during CI deploy validation
Wrangler now reports that the configured Worker could not be found in the account instead of incorrectly describing the failure as a name mismatch.
Ignore
.wranglerwrites in the dev assets watcherwrangler devreloaded in a loop whenassets.directorywas the project root, because the assets watcher treated wrangler's own writes under.wrangleras asset changes and dropped in-flight requests. The watcher now ignores the project's.wranglerdirectory anddev.persist, except when that path is the assets directory.Fix optional Docker lookups printing Docker CLI errors during successful builds
cf buildlooks for Container images left behind by earlier builds so it can remove them. This lookup is best effort, but when Docker could not be reached it still printed errors such asCannot connect to the Docker daemon, even when the build succeeded and no image needed Docker. Docker commands whose output Wrangler reads no longer forward the Docker CLI's error output to the terminal. If one of these commands fails in a way that stops the command, the error message still includes the Docker CLI's output.Time out the OAuth token request instead of waiting indefinitely
The request that exchanges an authorization code or refresh token for an access token had no timeout, so a stalled connection (for example behind an HTTP proxy) could leave
wrangler loginhanging silently for many minutes after the browser step had succeeded. The request now gives up after 30 seconds and reports that the Cloudflare auth server could not be reached.Preserve binding options when provisioning resources through a redirected config
Wrangler now writes provisioned resource identifiers to both the redirected and original config files without copying other binding options between them. This prevents generated relative paths such as D1
migrations_dirfrom replacing user-authored paths during Vite deployments.Honor
X-Forwarded-Protofor incoming development requests behind TLS-terminating proxiesMiniflare now uses the original client protocol when constructing URLs for network requests. This also prevents Wrangler from downgrading HTTPS URLs in response headers such as
LocationandWWW-Authenticatewhen a tunnel forwards requests over HTTP. Explicit programmatic request URLs and configured upstream origins remain authoritative.
4.149.0
8 Oct 2026Support temporary event accounts in R2 and Containers commands
wrangler r2andwrangler containerscommands now accept the hidden--temporaryflag, so accounts created for an event can manage buckets, objects and containers directly. Every command that supports--temporarynow also accepts a hidden--event-codeflag, so the first command a participant runs can create the event account:wrangler r2 bucket create my-bucket --temporary --event-code <code>R2 and Containers are only available on event accounts. R2 custom domains, Sippy, external container registries and
wrangler cloudchambercommands still require a logged-in account.Honor Retry-After directives during static asset uploads
Static asset uploads now pause retries and pending uploads until the latest outstanding deadline requested by the API. A per-request limiter also keeps gateway retries at the reduced concurrency after the pause ends, preventing a deployment from immediately overloading a constrained asset service again.
Document that
addressescatch-all entries must use the zone apexA
*@domainentry inaddressesmust use the zone apex, such as*@example.com. The zone catch-all also receives mail for every subdomain in the zone that has no literal rule.
Minor Changes
Support temporary event accounts in R2 and Containers commands
wrangler r2andwrangler containerscommands now accept the hidden--temporaryflag, so accounts created for an event can manage buckets, objects and containers directly. Every command that supports--temporarynow also accepts a hidden--event-codeflag, so the first command a participant runs can create the event account:wrangler r2 bucket create my-bucket --temporary --event-code <code>R2 and Containers are only available on event accounts. R2 custom domains, Sippy, external container registries and
wrangler cloudchambercommands still require a logged-in account.
Patch Changes
Honor Retry-After directives during static asset uploads
Static asset uploads now pause retries and pending uploads until the latest outstanding deadline requested by the API. A per-request limiter also keeps gateway retries at the reduced concurrency after the pause ends, preventing a deployment from immediately overloading a constrained asset service again.
Document that
addressescatch-all entries must use the zone apexA
*@domainentry inaddressesmust use the zone apex, such as*@example.com. The zone catch-all also receives mail for every subdomain in the zone that has no literal rule.Keep Preview secrets when deploying to an existing Preview
Secrets added to a Preview with
wrangler preview secret putorwrangler preview secret bulkwere lost the next timewrangler previewran, because each new deployment was created from the Wrangler config,--varand--secrets-filevalues only.wrangler previewnow carries over the secrets of the Preview's latest deployment. A value passed in this deployment (--secrets-file,--varor apreviewsbinding with the same name) still replaces the existing secret, andwrangler preview secret deleteremoves one.Stop the update check from recommending deprecated versions
Previously, the "update available" notice shown by
wranglerand@cloudflare/vite-pluginalways pointed at whichever version was taggedlateston npm, even after that version had been deprecated for shipping a bug. Deprecated versions are now never recommended: if the latest release has been deprecated, the newest non-deprecated stable release below it is suggested instead, or nothing at all if you are already on it.The check now reads the npm registry directly instead of going through the
update-checkpackage, which discarded the deprecation information. The on-disk cache location and one-hour refresh interval are unchanged.Ship
usingandawait usingdeclarations to the runtime as written, for smaller Worker bundlesWorkers and Pages Functions that use explicit resource management no longer carry about 1 KB of bundled helper code to emulate it. workerd supports
usingandawait usingnatively at every compatibility date, sowrangler deploy,wrangler versions uploadand Pages Functions builds now leave these declarations untouched.Apply each action's own condition in
wrangler r2 bucket lifecycle addWhen a lifecycle rule was added with both expiration and Infrequent Access transition flags, both actions read their condition from the same list of flags, which checked
--expire-daysfirst.--expire-days 365 --ia-transition-days 30therefore transitioned objects after 365 days instead of 30, and--expire-date 2027-01-01 --ia-transition-days 30deleted objects after 30 days instead of on the given date. Expiration now only reads--expire-days/--expire-date, and transition only reads--ia-transition-days/--ia-transition-date.
4.148.0
6 Oct 2026Add
--source-namespaceand--source-repo-nametowrangler queues subscription createfor theartifacts.reposourceThe Event Subscriptions API requires
source.namespaceandsource.repo_nameforartifacts.reposubscriptions, but Wrangler had no way to pass them, so--source artifacts.repoalways failed with a validation error. Both flags are now required for this source, andwrangler queues subscription getshows the subscription's resource as<namespace>/<repo-name>.Add
assets.base_pathsupport to Workers AssetsServe an asset directory from a public URL prefix without changing its on-disk layout:
{ "assets": { "directory": "./public", "base_path": "/docs" } }Wrangler, preview, Miniflare, and generated build configuration preserve the explicitly selected value, while the Asset Worker normalizes it and strips the prefix only for asset lookup. Requests passed to a user Worker, request-facing headers, and redirects retain the public path. Relative pathname inputs are interpreted as root-relative prefixes, URL-shaped values are rejected, and omitting the option preserves existing root-path behavior.
Authored
_headersand_redirectsrules continue to match full public paths. In particular, both the source and destination of an authored200asset rewrite must include the configured public prefix; Asset Worker-generated redirects are prefixed automatically.Add a
--experimental-mode instantoption towrangler kv namespace createThis lets entitled accounts create Workers KV Instant namespaces while the feature is in private beta.
Minor Changes
Add
--source-namespaceand--source-repo-nametowrangler queues subscription createfor theartifacts.reposourceThe Event Subscriptions API requires
source.namespaceandsource.repo_nameforartifacts.reposubscriptions, but Wrangler had no way to pass them, so--source artifacts.repoalways failed with a validation error. Both flags are now required for this source, andwrangler queues subscription getshows the subscription's resource as<namespace>/<repo-name>.Add
assets.base_pathsupport to Workers AssetsServe an asset directory from a public URL prefix without changing its on-disk layout:
{ "assets": { "directory": "./public", "base_path": "/docs" } }Wrangler, preview, Miniflare, and generated build configuration preserve the explicitly selected value, while the Asset Worker normalizes it and strips the prefix only for asset lookup. Requests passed to a user Worker, request-facing headers, and redirects retain the public path. Relative pathname inputs are interpreted as root-relative prefixes, URL-shaped values are rejected, and omitting the option preserves existing root-path behavior.
Authored
_headersand_redirectsrules continue to match full public paths. In particular, both the source and destination of an authored200asset rewrite must include the configured public prefix; Asset Worker-generated redirects are prefixed automatically.Add a
--experimental-mode instantoption towrangler kv namespace createThis lets entitled accounts create Workers KV Instant namespaces while the feature is in private beta.
Add email-protected Quick Tunnels to
wrangler devPass one or more
--tunnel-allowed-mailflags to require email authentication when exposing a local development server through a Quick Tunnel. Each value can be an exact email address or a domain pattern.Support deleting secrets with
wrangler versions secret bulkSet a secret's value to
nullin JSON input to remove it from the new Worker version. Bulk output now distinguishes between created and deleted secrets, so retryingwrangler secret bulkwithwrangler versions secret bulkpreserves requested deletions. Deploy the new version withwrangler versions deployto apply the changes to production traffic.
Patch Changes
Improve guidance for conflicting Wrangler configuration files
When user and generated deploy configurations are found under different base paths, Wrangler now identifies the expected deploy configuration location, suggests how to resolve the conflict, and links to the relevant documentation.
Include default module rules in generated Worker types
wrangler typesnow declares the built-in Text, Data, and WebAssembly module patterns even when they are not repeated in the Wrangler configuration, keeping generated types aligned with deployment behavior.Service-worker declaration files are emitted as global scripts so that the generated wildcard module types are visible to imports.
Directory-specific rules retain their scope when TypeScript can represent it; ambiguous relative imports use a union of the possible deployed module types.
When generating combined types for named environments, each environment's effective rules are resolved independently and differing import types are represented as unions.
Fix
r2 object putandr2 bulk putstoring a different key in local modeKeys that are not URL-safe were mangled on the way into local storage.
A key with a space or a non-ASCII character was stored under its percent-encoded name, so a later
r2 object getfor that key reported that the key does not exist.Two keys that differ only after a
#collapsed into a single object, and the second upload replaced the first.A key with a
%that is not a valid escape failed outright with "Invalid URL string.", and one with a valid escape, such as%41.txt, was stored asA.txt.
Spaces, non-ASCII characters,
#and%now survive the trip into local storage. Objects already in local state are left where they are.Show a useful error when
wrangler secret bulkhits an undeployed latest versionwrangler secret putalready explained this case (API error 10215).secret bulkjust dumped the raw API response, which for 10214 talks about logpush and tail_consumers even though you were only uploading secrets.Both commands now point at
wrangler versions secret …instead.Print temporary account notices to stderr
The terms notice, the proof-of-work message, and the "Temporary account ready" claim details printed by
--temporarynow go to stderr instead of stdout. Previously they corrupted command output on stdout, such as the JSON fromwrangler kv namespace list --temporaryor the raw value fromwrangler kv key get --temporary. Commands that lower the log level for--json, such aswrangler d1 execute --json --temporary, also hid the claim URL; it is now shown unless logging is disabled withWRANGLER_LOG=none.Scripts that read the claim URL from stdout should read stderr instead.
4.147.0
2 Oct 2026Allow
"us"as a jurisdiction for Container applicationsContainer placement constraints now accept
constraints.jurisdiction: "us"in Wrangler and typed Cloudflare configuration. This makes the US jurisdiction available alongside"eu"and"fedramp".Fix
wrangler containers listto report live instancesThe
LIVE INSTANCEScolumn now reports each application's active runtime instances instead of its configured instance count, matching the Cloudflare dashboard. JSON output continues to expose the configured count through the existinginstancesfield.Accept Durable Object application IDs in Containers commands
wrangler containers instancesandwrangler containers deletenow accept the 32-character hexadecimal application IDs returned for Durable Object-backed applications, in addition to legacy dashed UUIDs.
Minor Changes
Allow
"us"as a jurisdiction for Container applicationsContainer placement constraints now accept
constraints.jurisdiction: "us"in Wrangler and typed Cloudflare configuration. This makes the US jurisdiction available alongside"eu"and"fedramp".
Patch Changes
Fix
wrangler containers listto report live instancesThe
LIVE INSTANCEScolumn now reports each application's active runtime instances instead of its configured instance count, matching the Cloudflare dashboard. JSON output continues to expose the configured count through the existinginstancesfield.Accept Durable Object application IDs in Containers commands
wrangler containers instancesandwrangler containers deletenow accept the 32-character hexadecimal application IDs returned for Durable Object-backed applications, in addition to legacy dashed UUIDs.Retry transient API failures in
wrangler workflows instances listandwrangler workflows instances describePreviously, a single temporary 5xx response or dropped connection made these read-only commands exit with an error, even though the next request would have succeeded. They now use Wrangler's existing bounded API retry handling. The read that resolves
--id latestis retried too, which also benefits the otherwrangler workflows instancescommands that acceptlatest; the mutating requests they make afterwards are not retried. Persistent failures are still reported after the retries are exhausted, and under--jsonany retry notices are written to stderr so stdout stays valid JSON.
4.146.0
1 Oct 2026Support the new Workflows
createBatch()API in local developmentLocal Workflows bindings now accept object-form batches that create instances from a count or a list of instance options. The result includes handles for created instances and indexed per-instance errors, matching the runtime API while preserving the deprecated array form.
Add
--allowed-mailto the experimentalwrangler tunnel quick-startcommandThe option forwards exact email addresses, comma-separated lists, and wildcard domains to
cloudflared. It can be specified more than once to combine multiple recipient rules.Email-protected tunnels require
cloudflared2026.9.2 or later. Wrangler checks the selected binary before starting the tunnel and reports an upgrade error when it is incompatible.Mark
wrangler artifactscommands as open betaArtifacts has entered open beta, so the
wrangler artifactscommands no longer display a "private beta" label in help output and warnings.
Minor Changes
Support the new Workflows
createBatch()API in local developmentLocal Workflows bindings now accept object-form batches that create instances from a count or a list of instance options. The result includes handles for created instances and indexed per-instance errors, matching the runtime API while preserving the deprecated array form.
Add
--allowed-mailto the experimentalwrangler tunnel quick-startcommandThe option forwards exact email addresses, comma-separated lists, and wildcard domains to
cloudflared. It can be specified more than once to combine multiple recipient rules.Email-protected tunnels require
cloudflared2026.9.2 or later. Wrangler checks the selected binary before starting the tunnel and reports an upgrade error when it is incompatible.
Patch Changes
Mark
wrangler artifactscommands as open betaArtifacts has entered open beta, so the
wrangler artifactscommands no longer display a "private beta" label in help output and warnings.Keep colons in
wrangler tail --headerfilter valueswrangler tail --headersplits its argument into a header name and an optional value at the colon. It split at every colon and kept only the first two parts, so a value containing a colon was cut short:--header "Origin:https://app.example.com"filtered onhttps. The value now includes everything after the first colon, so URLs, ports and IPv6 addresses are sent to the tail filter intact.
4.145.0
30 Sep 2026Add native support for the Analytics SQL binding
Declare the zero-configuration binding in
wrangler.jsonwith"analytics": { "binding": "ANALYTICS" }. Wrangler uploads theanalyticsbinding type and proxies it to the remote service during local development, sowrangler devcan call the binding withoutunsafe.bindings.Graduate SQL, Catalog, and Pipelines under
wrangler basinout of beta to stableBasin SQL is now available under
wrangler basin sql, Basin Catalog operations are available underwrangler basin catalog, and Pipelines operations are available underwrangler basin pipelines. These commands are now stable, while the previouswrangler r2 sql,wrangler r2 bucket catalog, andwrangler pipelinescommand paths remain available as hidden compatibility aliases.The Basin SQL authentication environment variable is now
WRANGLER_BASIN_SQL_AUTH_TOKEN. Update any existingWRANGLER_R2_SQL_AUTH_TOKENconfiguration to use the new name. The fallback toCLOUDFLARE_API_TOKENremains available.Add beta K2 producer bindings for existing streams
Configure a stream created through Wrangler, the Dashboard, or the API in
wrangler.json:{ "k2": [ { "binding": "ORDERS", "stream": "0123456789abcdef0123456789abcdef" } ] }The binding supports
env.ORDERS.send([{ content: new TextEncoder().encode("order"), headers: { event: "order.created" } }]). Batches use either allArrayBufferor allUint8Arraycontent. Check the returnedsuccessvalue, handle rejected RPC promises, and retry only when the returned error explicitly allows it. Generated environment types describe this producer contract without requiring a separate application dependency.K2 requires an enabled account. Deployment credentials need Worker deployment and K2 configuration-read access. Default Wrangler logins now request the K2 OAuth scopes; existing OAuth users should run
wrangler loginagain to grant the new permissions. Development always uses a real K2 stream and may incur usage charges; no local simulator is provided. Theremotesetting can be omitted,remote: truesuppresses the usage warning, andremote: falseis rejected. Consumption is not part of this Worker binding.
Minor Changes
Add native support for the Analytics SQL binding
Declare the zero-configuration binding in
wrangler.jsonwith"analytics": { "binding": "ANALYTICS" }. Wrangler uploads theanalyticsbinding type and proxies it to the remote service during local development, sowrangler devcan call the binding withoutunsafe.bindings.Graduate SQL, Catalog, and Pipelines under
wrangler basinout of beta to stableBasin SQL is now available under
wrangler basin sql, Basin Catalog operations are available underwrangler basin catalog, and Pipelines operations are available underwrangler basin pipelines. These commands are now stable, while the previouswrangler r2 sql,wrangler r2 bucket catalog, andwrangler pipelinescommand paths remain available as hidden compatibility aliases.The Basin SQL authentication environment variable is now
WRANGLER_BASIN_SQL_AUTH_TOKEN. Update any existingWRANGLER_R2_SQL_AUTH_TOKENconfiguration to use the new name. The fallback toCLOUDFLARE_API_TOKENremains available.Add beta K2 producer bindings for existing streams
Configure a stream created through Wrangler, the Dashboard, or the API in
wrangler.json:{ "k2": [ { "binding": "ORDERS", "stream": "0123456789abcdef0123456789abcdef" } ] }The binding supports
env.ORDERS.send([{ content: new TextEncoder().encode("order"), headers: { event: "order.created" } }]). Batches use either allArrayBufferor allUint8Arraycontent. Check the returnedsuccessvalue, handle rejected RPC promises, and retry only when the returned error explicitly allows it. Generated environment types describe this producer contract without requiring a separate application dependency.K2 requires an enabled account. Deployment credentials need Worker deployment and K2 configuration-read access. Default Wrangler logins now request the K2 OAuth scopes; existing OAuth users should run
wrangler loginagain to grant the new permissions. Development always uses a real K2 stream and may incur usage charges; no local simulator is provided. Theremotesetting can be omitted,remote: truesuppresses the usage warning, andremote: falseis rejected. Consumption is not part of this Worker binding.Add beta K2 stream management commands
Use
wrangler k2 streams create order_events,wrangler k2 streams list,wrangler k2 streams get <stream-id>, andwrangler k2 streams delete <stream-id>to manage K2 streams. Creation enables Worker bindings but not HTTP ingestion by default, matching the dashboard. Pass--http-enabledto enable authenticated HTTP ingestion and print its endpoint. Creation prints the stream ID and a binding configuration with aYOUR_BINDING_NAMEplaceholder for the Worker's variable name, but does not edit the configuration file automatically.All four commands support
--json. Deletion requires confirmation, or--force/-yto skip it; use--force --jsonfor JSON deletion output. Creation also accepts retention, HTTP authentication, Worker-input, and CORS options; listing supports pagination and a name filter. Default Wrangler logins now requestk2.readandk2.write; existing OAuth users should runwrangler loginagain, or use a custom API token granting K2 Config Write. The account must be enabled for K2.
4.144.0
29 Sep 2026Add
--tty(-t) flag towrangler containers sshto force pseudo-terminal allocationOpenSSH only allocates a pseudo-terminal when no remote command is given, so interactive commands such as
wrangler containers ssh <ID> -- bashpreviously ran without a prompt or line editing. Pass--ttyto force one:wrangler containers ssh <ID> --tty -- bashSupport SSH settings for Durable Object-managed Containers in the configuration API
defineContainernow acceptssshandauthorizedKeyswithschedulingPolicy: "durable-object", matching thesshandauthorized_keysfields that Wrangler already supports for these Containers. Previously the schema rejected them, so they could not be set fromcloudflare.config.ts.defineContainer({ name: "sandbox", schedulingPolicy: "durable-object", ssh: { enabled: true }, authorizedKeys: [{ name: "laptop", publicKey: "ssh-ed25519 AAAA..." }], });
Minor Changes
Add
--tty(-t) flag towrangler containers sshto force pseudo-terminal allocationOpenSSH only allocates a pseudo-terminal when no remote command is given, so interactive commands such as
wrangler containers ssh <ID> -- bashpreviously ran without a prompt or line editing. Pass--ttyto force one:wrangler containers ssh <ID> --tty -- bashSupport SSH settings for Durable Object-managed Containers in the configuration API
defineContainernow acceptssshandauthorizedKeyswithschedulingPolicy: "durable-object", matching thesshandauthorized_keysfields that Wrangler already supports for these Containers. Previously the schema rejected them, so they could not be set fromcloudflare.config.ts.defineContainer({ name: "sandbox", schedulingPolicy: "durable-object", ssh: { enabled: true }, authorizedKeys: [{ name: "laptop", publicKey: "ssh-ed25519 AAAA..." }], });
4.143.1
29 Sep 2026Fix
wrangler devremote bindings forworkers.devsubdomains protected by AccessRunning
wrangler devwith remote bindings on an unpublished worker protected by Access (e.g. using a wildcard on your workers.dev domain) previously failed with a redirect loop. Wrangler now correctly authenticates remote bindings with Access in this situation.Upgrade the bundled capnweb implementation to 0.12.0
This updates the RPC implementation shipped in Miniflare and remote-binding proxy workers to the latest capnweb release.
Resolve the affected Undici dependency in new Wrangler and Vite plugin installs
Undici 7.29.1 fixes GHSA-3wwx-pv8p-q78v. Update the shared dependency catalog and matching types used by Miniflare and Wrangler so downstream installs can resolve the patched runtime without an application-level override. A published release is still required for consumers; this changeset does not alter already published package metadata.
Patch Changes
Fix
wrangler devremote bindings forworkers.devsubdomains protected by AccessRunning
wrangler devwith remote bindings on an unpublished worker protected by Access (e.g. using a wildcard on your workers.dev domain) previously failed with a redirect loop. Wrangler now correctly authenticates remote bindings with Access in this situation.Upgrade the bundled capnweb implementation to 0.12.0
This updates the RPC implementation shipped in Miniflare and remote-binding proxy workers to the latest capnweb release.
Resolve the affected Undici dependency in new Wrangler and Vite plugin installs
Undici 7.29.1 fixes GHSA-3wwx-pv8p-q78v. Update the shared dependency catalog and matching types used by Miniflare and Wrangler so downstream installs can resolve the patched runtime without an application-level override. A published release is still required for consumers; this changeset does not alter already published package metadata.
Fix custom-domain-only deploys failing for API tokens without Zone Workers Routes read permission
When
workers_devwas disabled androutescontained only entries withcustom_domain: true, every deploy after the first one fetched/zones/:zoneId/workers/routesto check for route conflicts, even though custom domains are not zone Workers Routes. Tokens scoped to Workers Scripts edit plus custom domains - withoutZone > Workers Routes > Read- failed with "No access to the specified resource" after the Worker version had already been uploaded. The conflict check now only covers non-custom-domain routes; custom domain conflicts continue to be reported by the custom domains changeset API.Report an unreachable auth server instead of an expired login when refreshing an OAuth token
When the OAuth token endpoint could not be reached (for example a DNS failure or a connection timeout), the refresh failure was reported as "Your auth token has expired and could not be refreshed", with advice to run
wrangler login; in an interactive terminal Wrangler also started a new browser login. A network failure says nothing about the stored refresh token, and a new login would need the same unreachable server. Wrangler now reports that the Cloudflare auth server could not be reached, leaves the stored credentials unchanged, and does not start a login, so the next run can refresh with the same token once the network is back.
4.143.0
28 Sep 2026Use
cf/configforcloudflare.config.tsauthoringExperimental
cloudflare.config.tsprojects must now importdefineConfig, bindings, triggers, and related helpers fromcf/config. Generated declarations from Wrangler and the Vite plugin also reference this package, so projects using the experimental configuration flow must addcfas a dependency.The Vite plugin no longer exports
@cloudflare/vite-plugin/experimental-config.wrangler/experimental-configremains available fordefineWranglerConfig, but no longer re-exports Cloudflare configuration helpers.
4.142.0
27 Sep 2026Support Workflows declared in
exportsonctx.exportsin local developmentA Workflow declared in a Worker's
exportsis now available onctx.exportsinwrangler dev, the Vite plugin and the Vitest plugin, with the same API as a Workflow binding:const instance = await ctx.exports.MyWorkflow.create({ params: { name: "World" }, });ctx.exportsandworkflowsbindings with the same Workflownameshare their instances, including instances created before the Workflow was declared inexports. Two Workers can't export the same Workflow name, and a binding to an exported Workflow must refer to the Worker and class that export it.getPlatformProxy()ignores Workflows declared inexports, since it doesn't run the Worker's code.wrangler workflowscommands run with--localalso work with Workflows declared only inexports, without aworkflowsbinding.In the Vitest plugin,
introspectWorkflow()andintrospectWorkflowInstance()still need a Workflow binding, and now explain how to add one when passed a Workflow fromctx.exports. Instances created throughctx.exportsare introspected too. Aworkflowsbinding whosescript_nameis the Worker's own name now resolves to the Worker itself again.
Minor Changes
Support Workflows declared in
exportsonctx.exportsin local developmentA Workflow declared in a Worker's
exportsis now available onctx.exportsinwrangler dev, the Vite plugin and the Vitest plugin, with the same API as a Workflow binding:const instance = await ctx.exports.MyWorkflow.create({ params: { name: "World" }, });ctx.exportsandworkflowsbindings with the same Workflownameshare their instances, including instances created before the Workflow was declared inexports. Two Workers can't export the same Workflow name, and a binding to an exported Workflow must refer to the Worker and class that export it.getPlatformProxy()ignores Workflows declared inexports, since it doesn't run the Worker's code.wrangler workflowscommands run with--localalso work with Workflows declared only inexports, without aworkflowsbinding.In the Vitest plugin,
introspectWorkflow()andintrospectWorkflowInstance()still need a Workflow binding, and now explain how to add one when passed a Workflow fromctx.exports. Instances created throughctx.exportsare introspected too. Aworkflowsbinding whosescript_nameis the Worker's own name now resolves to the Worker itself again.
4.141.0
25 Sep 2026Add Durable Objects code update strategies to Worker deployments
Use
--durable-objects-code-update-mode immediatewithwrangler deploy,wrangler versions deploy, andwrangler rollbackto update code without waiting for active instances to hibernate. Use--durable-objects-code-update-mode deferred 30sto set a maximum delay, or configuredurable_objects.code_update_strategywithmodeandmax_delay. When unset, the strategy defaults to deferred with a 5-minute maximum delay; delays cannot exceed 24 hours and must use millisecond precision.Add Browser Run as an event source for Queue subscriptions
You can now create Queue subscriptions with
--source browserRun.Show the stack and cause of failed proxied requests in
wrangler devdebug logsWhen a request proxied to the local Worker fails, running with
--log-level debugnow shows the underlying error's stack and cause chain.
Minor Changes
Add Durable Objects code update strategies to Worker deployments
Use
--durable-objects-code-update-mode immediatewithwrangler deploy,wrangler versions deploy, andwrangler rollbackto update code without waiting for active instances to hibernate. Use--durable-objects-code-update-mode deferred 30sto set a maximum delay, or configuredurable_objects.code_update_strategywithmodeandmax_delay. When unset, the strategy defaults to deferred with a 5-minute maximum delay; delays cannot exceed 24 hours and must use millisecond precision.Add Browser Run as an event source for Queue subscriptions
You can now create Queue subscriptions with
--source browserRun.
Patch Changes
Show the stack and cause of failed proxied requests in
wrangler devdebug logsWhen a request proxied to the local Worker fails, running with
--log-level debugnow shows the underlying error's stack and cause chain.
4.140.0
25 Sep 2026Support Containers in Worker Preview deployments with the Build Output.
Minor Changes
Support Containers in Worker Preview deployments with the Build Output.
4.139.0
24 Sep 2026Configure SSH for experimental Durable Object-managed Containers
Set
containers.sshandcontainers.authorized_keyswhen usingscheduling_policy: "durable_object". These are application-wide settings that follow the same rules as the existing Durable Object-managed Container settings: normal deployments create missing applications and update explicitly configured values, while omitted settings preserve the existing application configuration.// wrangler.jsonc { "containers": [ { "name": "sandbox", "class_name": "Sandbox", "scheduling_policy": "durable_object", "ssh": { "enabled": true }, "authorized_keys": [ { "name": "laptop", "public_key": "ssh-ed25519 AAAA..." } ] } ] }Expose configured Cron Triggers to local development consumers
Wrangler now passes the active environment's exact Cron Trigger expressions to Miniflare so Local Explorer can display them. Headless agent sessions also advertise the Local Explorer scheduled invocation API.
Support UDP connect handlers in local development
The experimental
connectconfiguration now acceptsprotocol: "udp", with optionalidle_timeout_msandmax_pending_bytessettings. UDP datagrams are delivered to the Worker'sconnect()handler using workerd's value-mode socket streams, and can be tested withMiniflare#dispatchConnect({ protocol: "udp" }).
Minor Changes
Configure SSH for experimental Durable Object-managed Containers
Set
containers.sshandcontainers.authorized_keyswhen usingscheduling_policy: "durable_object". These are application-wide settings that follow the same rules as the existing Durable Object-managed Container settings: normal deployments create missing applications and update explicitly configured values, while omitted settings preserve the existing application configuration.// wrangler.jsonc { "containers": [ { "name": "sandbox", "class_name": "Sandbox", "scheduling_policy": "durable_object", "ssh": { "enabled": true }, "authorized_keys": [ { "name": "laptop", "public_key": "ssh-ed25519 AAAA..." } ] } ] }Expose configured Cron Triggers to local development consumers
Wrangler now passes the active environment's exact Cron Trigger expressions to Miniflare so Local Explorer can display them. Headless agent sessions also advertise the Local Explorer scheduled invocation API.
Support UDP connect handlers in local development
The experimental
connectconfiguration now acceptsprotocol: "udp", with optionalidle_timeout_msandmax_pending_bytessettings. UDP datagrams are delivered to the Worker'sconnect()handler using workerd's value-mode socket streams, and can be tested withMiniflare#dispatchConnect({ protocol: "udp" }).Support
workflowentries in theexportsconfiguration mapA Worker can now declare the Workflows it defines in
exports, keyed by theWorkflowEntrypointclass name:{ "exports": { "MyWorkflow": { "type": "workflow", "name": "my-workflow", "limits": { "steps": 100 }, "schedules": "0 * * * *" } } }A
workflowexport accepts the same settings as aworkflowsbinding:limits,concurrency,schedules, anddefault_retention.wrangler deployandwrangler versions uploadsend these entries to the upload API by name, andwrangler deployandwrangler triggers deployprovision the Workflow with its settings, just as they do forworkflowsbindings owned by the Worker. A Workflow may be declared both as a binding and as an export, as long as both declarations use the same class and do not set the same setting to different values. A binding to another Worker's Workflow cannot share a name with an export.@cloudflare/configadds the matchingexports.workflow()helper. Local development does not yet act on these entries.
Patch Changes
Emulate the deterministic-ID uniqueness contract in the local Workflows binding
The local Workflows binding now matches the documented production behavior for deterministic instance IDs:
create({ id })with an ID that already exists throws(instance.already_exists)and retains the existing instance, andcreateBatch()skips IDs that already exist or repeat within the batch, excluding them from the result instead of creating duplicate executions. Previously both paths silently created duplicates, so code relying on deterministic IDs for idempotency (for example a Queue consumer creating one workflow per message) appeared to work locally while double-executing workflow bodies.Show
--jurisdictionin help forwrangler kv namespace createThe option was supported but omitted from the command's help output. Users can now discover how to create KV namespaces in a specific jurisdiction.
Update
smol-tomlto 1.9.0 to fix slow parsing of very large TOML filesParse time for TOML config files now grows linearly with their size, instead of with its square: a 40,000-line file that took 259 ms to parse now takes 17 ms, while typical
wrangler.tomlfiles parse in the same time as before. This addresses theGHSA-r4xh-jqrq-34v2advisory against earlier versions of the parser.Some TOML syntax errors now point at the character that caused them. For example, a
wrangler.tomlcontainingINVALID "FILEis now reported asillegal character in keyat the", rather thanincomplete key-valueat the start of the line.
4.138.0
24 Sep 2026Add event-code support to temporary Worker deployments
Use
wrangler deploy --temporary --event-code <code>to provision an account for an event. Wrangler requires explicit server acknowledgement before caching the account and keeps the event code out of its cache and telemetry.Allow framework commands to produce Preview Build Output with the experimental config
When
cf previews deployinvokes a framework build command, Preview intent is now preserved. Function-basedcloudflare.config.tsfiles receiveisPreview: true, and generated Build Output is marked as a Preview build.Standardize Zod validation error output
Format validation errors with Zod's built-in
prettifyError()helper so Miniflare, Wrangler, the Vite plugin, and the Vitest plugin show consistent messages and property paths.
Minor Changes
Add event-code support to temporary Worker deployments
Use
wrangler deploy --temporary --event-code <code>to provision an account for an event. Wrangler requires explicit server acknowledgement before caching the account and keeps the event code out of its cache and telemetry.Allow framework commands to produce Preview Build Output with the experimental config
When
cf previews deployinvokes a framework build command, Preview intent is now preserved. Function-basedcloudflare.config.tsfiles receiveisPreview: true, and generated Build Output is marked as a Preview build.
Patch Changes
Standardize Zod validation error output
Format validation errors with Zod's built-in
prettifyError()helper so Miniflare, Wrangler, the Vite plugin, and the Vitest plugin show consistent messages and property paths.
4.137.0
23 Sep 2026Generate types during development and supported builds with Vite's
experimental.newConfigoption or Wrangler's--experimental-new-configflag (and--experimental-cf-build-outputfor builds)When Wrangler's
--experimental-new-configflag or Vite'sexperimental.newConfigoption is enabled, inferred configuration and runtime declarations are now kept in.cloudflare/types/index.d.ts. Vite refreshes them during development and production builds. Wrangler refreshes them during development and when building with both--experimental-new-configand--experimental-cf-build-output. In the experimentalwrangler.config.tsformat, thetypesoption is now top-level because it applies to both commands.Prepare the required egress sidecar for local Containers without configured images
Wrangler dev and Vite dev/preview now pull the required sidecar for Durable Object-managed Containers that select their application image at start time. Previously, these Containers failed to start unless the sidecar image was already cached in Docker.
Match D1 SQL statement splitting to the local SQLite runtime
Wrangler now uses SQLite's statement-completion state machine when splitting D1 SQL files. This keeps trigger, quoted identifier, comment, and keyword handling consistent with local execution.
4.136.3
22 Sep 2026Update
smol-tomlto 1.8.0This updates the bundled TOML parser that reads
wrangler.tomlto a version that addresses two advisories against 1.5.2:GHSA-7w5x-hrqm-74c2(a value followed by a comment with no trailing newline, such asa=[1 #, put the parser in an infinite loop) andGHSA-v3rj-xjv7-4jmq(thousands of consecutive comment lines overflowed the stack). On the old version,wrangler deployagainst awrangler.tomlending ina=[1 #never returned; it now fails withInvalid TOML document: cannot find end of structure.Warn when
wrangler previewreturns only non-custom-domain URLs even though custom-domain Preview URLs are configured.Fix Preview output artifacts to always include the resolved parent Worker name
Preview artifacts now use Wrangler's resolved Worker name instead of relying on the Preview API response to include it.
Patch Changes
Update
smol-tomlto 1.8.0This updates the bundled TOML parser that reads
wrangler.tomlto a version that addresses two advisories against 1.5.2:GHSA-7w5x-hrqm-74c2(a value followed by a comment with no trailing newline, such asa=[1 #, put the parser in an infinite loop) andGHSA-v3rj-xjv7-4jmq(thousands of consecutive comment lines overflowed the stack). On the old version,wrangler deployagainst awrangler.tomlending ina=[1 #never returned; it now fails withInvalid TOML document: cannot find end of structure.Warn when
wrangler previewreturns only non-custom-domain URLs even though custom-domain Preview URLs are configured.Fix Preview output artifacts to always include the resolved parent Worker name
Preview artifacts now use Wrangler's resolved Worker name instead of relying on the Preview API response to include it.
4.136.2
22 Sep 2026Fix
wrangler typesgenerating runtime headers with trailing whitespaceRuntime type headers without compatibility flags now end at the compatibility date, keeping generated types reproducible when tools remove trailing whitespace.
Improve Container image listing and deletion
List all image pages using read-only credentials, validate tags before deletion, and report successful deletion when the garbage-collection request fails.
Fix Container SSH connection setup and shutdown
Prevent SSH connections from stalling during setup and ensure proxy processes exit when sessions close.
Patch Changes
Fix
wrangler typesgenerating runtime headers with trailing whitespaceRuntime type headers without compatibility flags now end at the compatibility date, keeping generated types reproducible when tools remove trailing whitespace.
Improve Container image listing and deletion
List all image pages using read-only credentials, validate tags before deletion, and report successful deletion when the garbage-collection request fails.
Fix Container SSH connection setup and shutdown
Prevent SSH connections from stalling during setup and ensure proxy processes exit when sessions close.
Show valid
sha256-prefixed tags in Container image listingsContainer image listings now distinguish valid OCI tags such as
sha256-releasefrom synthetic digest entries such assha256:<digest>.
4.136.1
21 Sep 2026Improve
wrangler previewonboarding guidanceWrangler now displays placeholder replacement guidance directly beneath the suggested Preview configuration instead of as a separate warning. JSON output continues to include the guidance in its structured onboarding messages.
Read workers.dev URLs from the Worker resource during deployment
Wrangler no longer requires account-level subdomain permission to display Worker and version-preview URLs. It now uses the Worker-scoped URL fields while preserving account-level registration for accounts without a workers.dev subdomain.
Patch Changes
Improve
wrangler previewonboarding guidanceWrangler now displays placeholder replacement guidance directly beneath the suggested Preview configuration instead of as a separate warning. JSON output continues to include the guidance in its structured onboarding messages.
Read workers.dev URLs from the Worker resource during deployment
Wrangler no longer requires account-level subdomain permission to display Worker and version-preview URLs. It now uses the Worker-scoped URL fields while preserving account-level registration for accounts without a workers.dev subdomain.
4.136.0
21 Sep 2026Identify experimental Build Output resource configs by filename and location
The root remains
config.json, Worker configs are nowworker.config.json, and Container configs are nowcontainer.config.json. Resource configs no longer contain top-leveltypediscriminators, while settings and build context are stored together in the root config.Define experimental Cloudflare configuration with a single default export
Experimental
cloudflare.config.tsfiles now define settings and resources together in a default-exporteddefineConfig()call. Add a Worker underworker, add Containers to thecontainersarray, or omit both to provide settings only.import * as entrypoint from "./src/index.ts" with { type: "cf-worker" }; export default defineConfig({ accountId: "...", complianceRegion: "public", worker: { name: "my-worker", compatibilityDate: "2026-09-18", entrypoint, }, });Add experimental
--zoneand--zone-idflags towrangler deployandwrangler triggers deployto attach a zone to routes passed via--routeRoutes passed on the command line were always sent to the Cloudflare API as bare patterns. Zones with an SSL for SaaS entitlement reject such routes with error 10082 ("When using wildcard host ssl for saas entitlement you must specify the zone per route using zone_id or zone_name"), and until now the only way to set a zone was in the config file, which
--routeoverrides.The new flags are experimental and must be enabled with
--experimental-route-zones(alias--x-route-zones). Pass a single zone to apply it to all routes, or one zone per route in the same order as the--routeflags:wrangler deploy --x-route-zones --route "app.example.com/*" --route "api.example.com/*" --zone example.comwrangler deploy --x-route-zones --route "a.example.com/*" --zone example.com --route "b.example.net/*" --zone example.net--zonesetszone_nameand--zone-idsetszone_idon each route. The two flags cannot be combined, and passing more than one zone requires exactly one per--route. Routes without zone flags behave exactly as before.
Minor Changes
Identify experimental Build Output resource configs by filename and location
The root remains
config.json, Worker configs are nowworker.config.json, and Container configs are nowcontainer.config.json. Resource configs no longer contain top-leveltypediscriminators, while settings and build context are stored together in the root config.Define experimental Cloudflare configuration with a single default export
Experimental
cloudflare.config.tsfiles now define settings and resources together in a default-exporteddefineConfig()call. Add a Worker underworker, add Containers to thecontainersarray, or omit both to provide settings only.import * as entrypoint from "./src/index.ts" with { type: "cf-worker" }; export default defineConfig({ accountId: "...", complianceRegion: "public", worker: { name: "my-worker", compatibilityDate: "2026-09-18", entrypoint, }, });Add experimental
--zoneand--zone-idflags towrangler deployandwrangler triggers deployto attach a zone to routes passed via--routeRoutes passed on the command line were always sent to the Cloudflare API as bare patterns. Zones with an SSL for SaaS entitlement reject such routes with error 10082 ("When using wildcard host ssl for saas entitlement you must specify the zone per route using zone_id or zone_name"), and until now the only way to set a zone was in the config file, which
--routeoverrides.The new flags are experimental and must be enabled with
--experimental-route-zones(alias--x-route-zones). Pass a single zone to apply it to all routes, or one zone per route in the same order as the--routeflags:wrangler deploy --x-route-zones --route "app.example.com/*" --route "api.example.com/*" --zone example.comwrangler deploy --x-route-zones --route "a.example.com/*" --zone example.com --route "b.example.net/*" --zone example.net--zonesetszone_nameand--zone-idsetszone_idon each route. The two flags cannot be combined, and passing more than one zone requires exactly one per--route. Routes without zone flags behave exactly as before.Remove the experimental Container image environment binding
Durable Object-managed Containers now use
ctx.container.imageswithout Wrangler generatingenv.EXPERIMENTAL_CLOUDFLARE_CONTAINER_IMAGES. Update code using the experimental environment binding to readctx.container.imagesand regenerate your Worker types.Version deployments identify managed applications from native named images, and
--containers-rollout=nonepreserves native Container metadata. Containers without named images must first be provisioned withwrangler deploy;versions uploadverifies that their applications already exist. The old binding is no longer read or reserved, including on previously uploaded versions.keep_varsretains existing variables as usual; redeploy without it to remove an existing experimental binding.Return structured configuration errors from
wrangler preview --jsonWhen a Worker is missing its Preview configuration, JSON mode now returns an
error, asuggested_configpatch, and any associated onboardingmessageswithout interactive output or terminal formatting. This changes the private-beta Preview command to make automated onboarding reliable.Add support for jurisdictions to Queues subcommands
Patch Changes
Allow local Container images without exposed ports
Wrangler and the Cloudflare Vite plugin no longer reject images that omit Docker
EXPOSEmetadata. Local Containers can run command-only workloads or serve traffic through workerd without declaring an unused image port.Fix cf builds for static projects that serve assets from the project root
The experimental Build Output path now omits the reserved
.cloudflaredirectory when the project root is used for static assets. This prevents recursive output copying in Wrangler while preserving the existing behaviour for other asset directories.Rebase absolute non-JavaScript module specifiers when
preserve_file_namesis enabledWith
preserve_file_namesset, a non-JS module imported by an absolute path kept that path as its module name. The build machine's filesystem layout ended up inside the deployed Worker, and the module was never written to--outdir. A local dry run reported success while the upload failed server-side with error code10021. Tooling that rewrites externals to absolute paths hits this, which is how it was found in@opennextjs/cloudflarewith WASM imports.Absolute specifiers are now rebased to
./<basename>, which is what the hashed branch of the same code already does minus the hash prefix. Relative specifiers keep the behaviour they had.
4.135.0
18 Sep 2026Build Containers when emitting experimental Build Output
Wrangler and the Cloudflare Vite plugin now build Dockerfile-backed Container images when experimental Build Output is enabled. Container configs are emitted under
.cloudflare/output/v0/containerswith local image references, while existing registry references pass through unchanged.Evaluate Flagship flags locally during development
Flagship bindings now use the local Miniflare store by default in Wrangler and the Vite plugin, keeping development offline and isolated from production flags. Set
remote: trueon a binding to continue using its remote app.Use
wrangler flagship flags pull <APP_ID>to seed the store from a remote app. Flag management commands also accept--localto read and update the local store directly.Pass Preview intent to
defineWorkerand upload its resolved configurationPreview builds now evaluate programmatic Worker configuration with
ctx.isPreviewset totrueand record that intent in Build Output. The shared Preview uploader deploys the resolved bindings and settings while preserving configured Preview base values when it creates a Preview.
Minor Changes
Build Containers when emitting experimental Build Output
Wrangler and the Cloudflare Vite plugin now build Dockerfile-backed Container images when experimental Build Output is enabled. Container configs are emitted under
.cloudflare/output/v0/containerswith local image references, while existing registry references pass through unchanged.Evaluate Flagship flags locally during development
Flagship bindings now use the local Miniflare store by default in Wrangler and the Vite plugin, keeping development offline and isolated from production flags. Set
remote: trueon a binding to continue using its remote app.Use
wrangler flagship flags pull <APP_ID>to seed the store from a remote app. Flag management commands also accept--localto read and update the local store directly.Pass Preview intent to
defineWorkerand upload its resolved configurationPreview builds now evaluate programmatic Worker configuration with
ctx.isPreviewset totrueand record that intent in Build Output. The shared Preview uploader deploys the resolved bindings and settings while preserving configured Preview base values when it creates a Preview.
Patch Changes
Fix duration calculation for running workflow instances, steps, and attempts in
wrangler workflows instances describewrangler workflows instances describepreviously distorted the elapsed duration of in-progress instances, steps, and attempts across non-UTC timezones by stripping" GMT"fromtoUTCString(), causingnew Date(...)to parse the timestamp in the local client timezone. The duration is now correctly computed against the current time.
4.134.0
17 Sep 2026Add support for configuring real-time Issues with
observability.issues.enabledWrangler now validates and uploads the Issues setting alongside the existing logs and traces observability options. The experimental configuration format supports the equivalent
observability.issues.enabledoption.Mark
wrangler previewcommands as open betaWrangler now labels Preview commands as open beta in help output and command warnings, matching the feature's public availability.
Support explicit named Container image selection in Wrangler local development
Wrangler builds or pulls named images configured through Wrangler JSON or TOML and exposes their local tags through
ctx.container.images. Pass one of those references toctx.container.start({ image })to select the image.This extends the experimental Durable Object-managed Containers interface. Named images are opt-in and do not become the Container's default image. A Container without a default image must supply an image or full Container snapshot when starting.
Minor Changes
Add support for configuring real-time Issues with
observability.issues.enabledWrangler now validates and uploads the Issues setting alongside the existing logs and traces observability options. The experimental configuration format supports the equivalent
observability.issues.enabledoption.Mark
wrangler previewcommands as open betaWrangler now labels Preview commands as open beta in help output and command warnings, matching the feature's public availability.
Support explicit named Container image selection in Wrangler local development
Wrangler builds or pulls named images configured through Wrangler JSON or TOML and exposes their local tags through
ctx.container.images. Pass one of those references toctx.container.start({ image })to select the image.This extends the experimental Durable Object-managed Containers interface. Named images are opt-in and do not become the Container's default image. A Container without a default image must supply an image or full Container snapshot when starting.
4.133.0
16 Sep 2026Add placement configuration for Previews
You can now configure
placementin thepreviewsblock. Preview-specific placement overrides the top-level placement configuration for Preview Defaults and deployments.Improve onboarding guidance for Previews (when
previewsblock is missing from configuration file)When a local
previewsblock is absent, Wrangler writes the Preview Base configuration to the local config file. When no Preview Base configuration exists, Wrangler prints a placeholder configuration derived from production bindings and warns against reusing production binding configuration.Align Local Explorer Workflow instance status requests with production
Local Explorer and Wrangler local mode now use the production-compatible
statusrequest field for pausing, resuming, restarting, and terminating Workflow instances. Direct Local Explorer API consumers must replace the previousactionfield withstatus.Successful Local Explorer status updates now return the production-compatible instance
statusand responsetimestampinstead of the local-onlyresult.successacknowledgement.
Minor Changes
Add placement configuration for Previews
You can now configure
placementin thepreviewsblock. Preview-specific placement overrides the top-level placement configuration for Preview Defaults and deployments.Improve onboarding guidance for Previews (when
previewsblock is missing from configuration file)When a local
previewsblock is absent, Wrangler writes the Preview Base configuration to the local config file. When no Preview Base configuration exists, Wrangler prints a placeholder configuration derived from production bindings and warns against reusing production binding configuration.
Patch Changes
Align Local Explorer Workflow instance status requests with production
Local Explorer and Wrangler local mode now use the production-compatible
statusrequest field for pausing, resuming, restarting, and terminating Workflow instances. Direct Local Explorer API consumers must replace the previousactionfield withstatus.Successful Local Explorer status updates now return the production-compatible instance
statusand responsetimestampinstead of the local-onlyresult.successacknowledgement.Send exports with Worker Preview deployments
wrangler previewdropped theexportsblock from deployment requests. Durable Objects reached throughctx.exportshad no Preview namespace, and cache settings for each entrypoint were lost too.
4.132.0
15 Sep 2026Categorise the positional path argument to
wrangler deployandwrangler versions uploadin command telemetryCommand telemetry now records a coarse category for the entry-point/assets positional (
wrangler deploy <path>) undersanitizedArgs.path, so we can understand whether people pass a file, a directory, or a relational reference such as.or../example. The possible values arefile,directory,current-dir,parent-relative, andnot-found, ornullwhen no positional is provided. The raw path is never sent — only the category.Configure application-wide logs for experimental Durable Object-managed Containers
Set
containers.observability.enabledorcontainers.observability.logs.enabledwhen usingscheduling_policy: "durable_object". Normal deployments create missing applications and update explicitly configured log settings without a Container rollout. Omitted settings preserve the application configuration; root Worker observability is not inherited for this policy.Version uploads may initialize missing applications but preserve existing settings. Deploying or rolling back Worker versions also preserves existing application settings, and
--containers-rollout=noneskips their updates.Support per-image build options for experimental Durable Object-managed Containers
Set
build_contextandbuild_varsalongsidedockerfilein a Container's namedimagesentries. Context paths resolve relative to the Wrangler configuration file and default to the Dockerfile's directory. Build variables are passed as Docker build arguments. Entries using the same Dockerfile with different contexts or variables are built separately.{ "containers": [ { "class_name": "Sandbox", "scheduling_policy": "durable_object", "images": { "app": { "dockerfile": "./docker/Dockerfile", "build_context": ".", "build_vars": { "APP_ENV": "production" } } } } ] }
Minor Changes
Categorise the positional path argument to
wrangler deployandwrangler versions uploadin command telemetryCommand telemetry now records a coarse category for the entry-point/assets positional (
wrangler deploy <path>) undersanitizedArgs.path, so we can understand whether people pass a file, a directory, or a relational reference such as.or../example. The possible values arefile,directory,current-dir,parent-relative, andnot-found, ornullwhen no positional is provided. The raw path is never sent — only the category.Configure application-wide logs for experimental Durable Object-managed Containers
Set
containers.observability.enabledorcontainers.observability.logs.enabledwhen usingscheduling_policy: "durable_object". Normal deployments create missing applications and update explicitly configured log settings without a Container rollout. Omitted settings preserve the application configuration; root Worker observability is not inherited for this policy.Version uploads may initialize missing applications but preserve existing settings. Deploying or rolling back Worker versions also preserves existing application settings, and
--containers-rollout=noneskips their updates.Support per-image build options for experimental Durable Object-managed Containers
Set
build_contextandbuild_varsalongsidedockerfilein a Container's namedimagesentries. Context paths resolve relative to the Wrangler configuration file and default to the Dockerfile's directory. Build variables are passed as Docker build arguments. Entries using the same Dockerfile with different contexts or variables are built separately.{ "containers": [ { "class_name": "Sandbox", "scheduling_policy": "durable_object", "images": { "app": { "dockerfile": "./docker/Dockerfile", "build_context": ".", "build_vars": { "APP_ENV": "production" } } } } ] }Support AI Search bindings in Worker Previews
wrangler previewnow acceptsai_searchandai_search_namespacesentries in thepreviewsblock and includes them in Preview deployment bindings. This lets Workers that use AI Search instance or namespace bindings attach existing resources to Preview deployments, including preview-specific instance or namespace names.These bindings are non-inheritable: declare them explicitly under
previews. They attach to existing AI Search resources; preview does not provision new isolated instances or namespaces.[private beta]: Add
--secrets-fileand--varflags towrangler previewLike
wrangler deployandwrangler versions upload,wrangler previewnow accepts a--secrets-fileflag pointing to a JSON or .env format file, and--var KEY:VALUEpairs that are injected into the Preview deployment as plain text variables. CLI vars override same-named vars from thepreviewssection of your config file, and secrets from the file take precedence over both:wrangler preview --secrets-file .env.preview --var API_URL:https://api.example.comRemove the gated Web Search binding and Wrangler command
The unreleased search binding and its experimental command have been removed from Wrangler, Miniflare, and configuration APIs.
Allow experimental Durable Object-managed Containers to link by name through exports
Containers using
scheduling_policy: "durable_object"can now specifynameand link fromexports.<Class>.containerwithout repeatingclass_name. Deploy and version upload resolve that link for image preparation, Worker metadata, and Container application creation.
Patch Changes
Sync Local Explorer endpoint lists across agent hints
The Local Explorer endpoint list is now consistent across the three places it appears: the AGENTS.md template in
create-cloudflare, the runtime agent hint inwrangler dev, and the Vite plugin agent hint. All three now include theobservability/clearendpoint, use the canonical/cdn-cgi/local/explorerpath, and have cross-reference comments pointing to each other.Fix per-query overrides for
wrangler ai-search search--score-threshold,--max-num-results,--filter, and--rerankingare now sent using the AI Search request schema, so the service applies them to searches instead of ignoring them.Surface the original error message, name and stack when the dev server reports an internal error
Previously
wrangler devcould exit with an empty✘ [ERROR]log that gave no indication of what went wrong (e.g.Network connection lost., see #14641). These errors now include their original message, name and stack, so the failure is actually diagnosable.Treat 502, 503, and 504 as gateway errors during asset upload retries
Pages and Workers asset uploads now retry more patiently when the Cloudflare API responds with a 502, 503 or 504 gateway error, reducing concurrency and waiting longer between attempts instead of failing the deploy quickly.
Improve over-limit
run_worker_firsterrors when duplicate rules are presentThe error now reports distinct and duplicate-entry counts and lists duplicated rules, making it clear when removing redundant entries can bring the configuration within the limit.
Too many `run_worker_first` rules were provided; 105 rules provided (99 distinct, 6 duplicate entries) exceeds max of 100. Note: duplicate entries count towards the route limit. Ensure that no duplicate rules are present in your `run_worker_first` configuration. The duplicated rules found are: - "/rule/0" - "/rule/1" - "/rule/2" - "/rule/3" - "/rule/4" ...and 1 more duplicated rule.
Replace
execawithtinyexecfor running subprocesses, shrinking the bundled Wrangler output.Preserve service-worker middleware error propagation with spec-compliant event dispatch
Wrangler's synthetic service-worker events now propagate listener exceptions to middleware without changing the behavior of user-created
EventTargetinstances.Reduce the size of Wrangler's published package
Exclude test-only, build-only, and obsolete template files from the npm package while retaining all runtime templates.
Restore static asset upload concurrency after gateway errors
Static asset uploads previously remained at concurrency one for the rest of the deployment after any 524 response, which could make large deployments exceed the upload session lifetime. Successful uploads now restore the session's original concurrency gradually while retaining gateway throttling. Requests that were already in flight when throttling began do not restore capacity, so a burst of stale successes cannot immediately undo backpressure.
4.131.2
14 Sep 2026Only updates a dependency:miniflare 5.20260911.1-alpha
4.131.1
11 Sep 2026Add a provisioning delay note when custom domain Preview URLs change
Wrangler now explains that DNS and TLS certificate provisioning may continue after a deploy adds a custom domain or enables its Preview URLs. Stable redeploys don't repeat the note.
This assumes that a request which matches the stored custom domain state doesn't restart provisioning. The client infers this from the API changeset and current domain record because this repository can't verify the backend behavior.
Clarify production status labels for custom domain routes
Wrangler now prefixes explicit custom domain production states with
production:so they match Preview labels. The updated labels appear in deployed trigger output andWRANGLER_OUTPUT_FILE_PATH.Avoid replacement prompts for custom domains already on the Worker
Wrangler now updates Preview settings without asking to replace a custom domain when that domain already belongs to the deployed Worker. It still asks before replacing domains attached to another Worker.
Patch Changes
Add a provisioning delay note when custom domain Preview URLs change
Wrangler now explains that DNS and TLS certificate provisioning may continue after a deploy adds a custom domain or enables its Preview URLs. Stable redeploys don't repeat the note.
This assumes that a request which matches the stored custom domain state doesn't restart provisioning. The client infers this from the API changeset and current domain record because this repository can't verify the backend behavior.
Clarify production status labels for custom domain routes
Wrangler now prefixes explicit custom domain production states with
production:so they match Preview labels. The updated labels appear in deployed trigger output andWRANGLER_OUTPUT_FILE_PATH.Avoid replacement prompts for custom domains already on the Worker
Wrangler now updates Preview settings without asking to replace a custom domain when that domain already belongs to the deployed Worker. It still asks before replacing domains attached to another Worker.
Explain how to enable Preview URLs when a Preview deployment has none
wrangler previewnow shows URL shapes and configuration snippets for Workers.dev and custom domains. The custom domain snippet preserves every configured route, and the guidance distinguishes missing settings from disabled ones.This changes a private beta feature. The warning also makes clear that
wrangler deploypublishes code from the current checkout.
4.131.0
10 Sep 2026Add Durable Object-managed Containers to top-level container configuration
Wrangler now accepts
scheduling_policy: "durable_object"in the top-levelcontainersarray and creates its namespace-backed application after the Worker upload resolves the Durable Object namespace ID. The namespace ID is also the application ID, so repeated deploys idempotently ensure the same application without name-based lookup, modification, or a Containers rollout.Durable Object-managed entries accept
class_name,scheduling_policy, an optionalname, and an optional namedimagesmap. Scheduler-only fields are rejected. Each image provides either a localdockerfileor a digest-pinned managed-registryimage. Wrangler builds or resolves each image, waits while Cloudflare prepares it for the Containers runtime, and uploads the resulting references with the Worker version for access throughctx.container.imagesandenv.EXPERIMENTAL_CLOUDFLARE_CONTAINER_IMAGES. Local development support for these entries is deferred to a follow-up.Existing scheduler-backed entries and Durable Object migrations continue to work unchanged.
With
--containers-rollout=none, existing Workers retain their deployed Container metadata and image binding even when localcontainersis omitted or empty; local scheduler edits are also ignored. The upload stops if the deployed versions cannot be recovered. Existing Workers for Platforms dispatch scripts reject this flag before upload because their API does not expose enough metadata to preserve Container associations safely. First deployments can still skip Container preparation and rollout. Without this flag, removing managed Containers, including by omittingcontainersentirely, clears the experimental image binding even withkeep_vars.versions deployvalidates the selected versions before changing traffic and creates their Durable Object-managed applications only after deployment succeeds. Bothdeployandversions deployreport partial completion if application creation fails afterward, with instructions to retry the same command.EXPERIMENTAL_CLOUDFLARE_CONTAINER_IMAGESis a temporary, reserved Wrangler binding until native Container image metadata is available. Its class keys identify managed applications duringversions deploy, including classes with empty image maps. User configuration cannot declare a binding with this name; existing versions that already use it are treated as Container configuration.Remove
wrangler preview settingscommandsThe private-beta
wrangler preview settingsandwrangler preview settings updatecommands are no longer available.Fail
wrangler versions uploadearly when a Worker has a pending Durable Object migrationWrangler now directs users to run
wrangler deployto apply the migration instead of sending a version upload request that the API will reject.
Minor Changes
Add Durable Object-managed Containers to top-level container configuration
Wrangler now accepts
scheduling_policy: "durable_object"in the top-levelcontainersarray and creates its namespace-backed application after the Worker upload resolves the Durable Object namespace ID. The namespace ID is also the application ID, so repeated deploys idempotently ensure the same application without name-based lookup, modification, or a Containers rollout.Durable Object-managed entries accept
class_name,scheduling_policy, an optionalname, and an optional namedimagesmap. Scheduler-only fields are rejected. Each image provides either a localdockerfileor a digest-pinned managed-registryimage. Wrangler builds or resolves each image, waits while Cloudflare prepares it for the Containers runtime, and uploads the resulting references with the Worker version for access throughctx.container.imagesandenv.EXPERIMENTAL_CLOUDFLARE_CONTAINER_IMAGES. Local development support for these entries is deferred to a follow-up.Existing scheduler-backed entries and Durable Object migrations continue to work unchanged.
With
--containers-rollout=none, existing Workers retain their deployed Container metadata and image binding even when localcontainersis omitted or empty; local scheduler edits are also ignored. The upload stops if the deployed versions cannot be recovered. Existing Workers for Platforms dispatch scripts reject this flag before upload because their API does not expose enough metadata to preserve Container associations safely. First deployments can still skip Container preparation and rollout. Without this flag, removing managed Containers, including by omittingcontainersentirely, clears the experimental image binding even withkeep_vars.versions deployvalidates the selected versions before changing traffic and creates their Durable Object-managed applications only after deployment succeeds. Bothdeployandversions deployreport partial completion if application creation fails afterward, with instructions to retry the same command.EXPERIMENTAL_CLOUDFLARE_CONTAINER_IMAGESis a temporary, reserved Wrangler binding until native Container image metadata is available. Its class keys identify managed applications duringversions deploy, including classes with empty image maps. User configuration cannot declare a binding with this name; existing versions that already use it are treated as Container configuration.Remove
wrangler preview settingscommandsThe private-beta
wrangler preview settingsandwrangler preview settings updatecommands are no longer available.
Patch Changes
Fail
wrangler versions uploadearly when a Worker has a pending Durable Object migrationWrangler now directs users to run
wrangler deployto apply the migration instead of sending a version upload request that the API will reject.Detect named-only module Worker entrypoints correctly
Wrangler now distinguishes named-only module Workers from legacy Service Workers that happen to have named exports. A default export identifies a module Worker; otherwise, legacy
addEventListenerregistration identifies Service Worker format.Correct Pages-to-Workers delegation analytics for forced and ineligible commands
The legacy
forcedresult counted every agent-driven Pages command using--force, including commands that could never have been delegated. Wrangler now emitseligible_forcedonly when--forceprevents an otherwise eligible delegation, and records other agent commands asineligiblewith a bounded reason and whether force was used.Prevent delayed internal errors from fetch-only remote bindings
Fetch-only remote bindings such as D1 and R2 previously opened an unused WebSocket RPC session. RPC sessions are now created only when an RPC method is called.
Add the missing
transferred_classesmigration to the config schemaDurableObjectMigrationdescribednew_classes,new_sqlite_classes,renamed_classesanddeleted_classes, but nottransferred_classes.normalizeAndValidateConfighas always validated that key, and the deploy path forwards it to the API along with the rest of the step, so Transfer migrations worked — butconfig-schema.jsonis generated from the type, so an editor resolving$schemareported a valid, documented migration as an unknown key.Adding the field to the type puts it in the generated schema. No runtime change.
Bump
shell-quoteto 1.9.0+ to pick up two disclosed advisoriesshell-quote@1.8.1is affected by a ReDoS inparse()(CVE-2026-13311 / GHSA-395f-4hp3-45gv — an unauthenticated attacker who can feed a string intoparse()can block the event loop for tens of seconds with plain space-separated input, no shell metacharacters required) and by an object-token escaping bug inquote()(CVE-2026-9277 / GHSA-w7jw-789q-3m8p), both fixed upstream in1.9.0. Wrangler'sparse()wrapper (src/utils/shell-quote.ts) is reachable frompages dev/initcommand-line parsing, so the ReDoS applies; thequote()call site only ever passes string arguments, so the object-token issue was not reachable here, but there is no reason to stay on a vulnerable range once a patch exists.Encode filenames in Pages HTML redirects
Fix
wrangler pages devreturning a 502 response when redirecting HTML paths containing Unicode characters. Keep reserved characters in filenames encoded in the redirect destination and preserve the request query string.Fix
wrangler types --strict-vars=falseemitting invalid TypeScript for an empty array varA var whose value was an empty array produced
(), which is a syntax error. Because this lands in the generatedworker-configuration.d.ts, it did not just break that one line — the whole file failed to parse, so no binding types resolved at all. An empty array now generatesunknown.Use
previews_base_configfor Preview configurationPreview commands now read the Worker Previews Base configuration from the
previews_base_configAPI field.Fix
wrangler workflows instances describecrashing on dynamic retry delaysThe Workflows API serializes function retry delays as
"[dynamic]". The describe command previously parsed that as a duration, produced an Invalid Date, and threwRangeError: Invalid time valuebefore printing remaining steps. It now rendersunknown (dynamic delay)and also tolerates attempts whoseendtimestamp is missing.
4.130.0
8 Sep 2026Add
containers.observabilitysupport towrangler deployWrangler now accepts container-specific observability settings via
containers.observability, including application-level targeting fields for Containers. Rootobservabilitycontinues to work as a fallback when a container does not define its own observability settings.wrangler deploynow preserves legacyconfiguration.observabilityfor existing container apps that still use rollout-based observability, while using top-level application observability for new or already-migrated apps.Existing application diffs are now normalized even when stored resource limits cannot be mapped to a named instance type. API-only metadata and equivalent managed-registry image names no longer appear as edits or affect whether deployment changes require a rollout.
Delegate agent Pages project creation with a production branch to Workers
When run by an AI agent,
wrangler pages project create --production-branch <name>is now eligible for delegation to a Workers static-assets deploy. The production branch names the target that a Workers deploy would publish to, so it does not need to disqualify a brand-new project from delegation.wrangler pages deploy --branch <name>remains on Pages because an interactive new-project flow separately prompts for its production branch. The deployment branch may therefore represent a preview and cannot safely be converted into a production Workers deployment.Widen agent Pages-to-Workers delegation to new projects on accounts that already use Pages
When run by an AI agent,
wrangler pages deployandwrangler pages project createnow delegate a brand-new static Pages project to a Workers static-assets deploy even when the account already has other Pages projects. The gate is now per-project rather than per-account: a command targeting a project that already exists stays on Pages, but a new project is delegated regardless of the account's other Pages projects.A project name restored from the Pages configuration cache is only used when the cache belongs to the currently authenticated account. An account-matching cached name remains on Pages even when the project is missing remotely, preserving the user's recorded Pages intent. After switching accounts, an otherwise unnamed deploy stays on Pages rather than treating a stale cached project name as a new project on the selected account.
Minor Changes
Add
containers.observabilitysupport towrangler deployWrangler now accepts container-specific observability settings via
containers.observability, including application-level targeting fields for Containers. Rootobservabilitycontinues to work as a fallback when a container does not define its own observability settings.wrangler deploynow preserves legacyconfiguration.observabilityfor existing container apps that still use rollout-based observability, while using top-level application observability for new or already-migrated apps.Existing application diffs are now normalized even when stored resource limits cannot be mapped to a named instance type. API-only metadata and equivalent managed-registry image names no longer appear as edits or affect whether deployment changes require a rollout.
Delegate agent Pages project creation with a production branch to Workers
When run by an AI agent,
wrangler pages project create --production-branch <name>is now eligible for delegation to a Workers static-assets deploy. The production branch names the target that a Workers deploy would publish to, so it does not need to disqualify a brand-new project from delegation.wrangler pages deploy --branch <name>remains on Pages because an interactive new-project flow separately prompts for its production branch. The deployment branch may therefore represent a preview and cannot safely be converted into a production Workers deployment.Widen agent Pages-to-Workers delegation to new projects on accounts that already use Pages
When run by an AI agent,
wrangler pages deployandwrangler pages project createnow delegate a brand-new static Pages project to a Workers static-assets deploy even when the account already has other Pages projects. The gate is now per-project rather than per-account: a command targeting a project that already exists stays on Pages, but a new project is delegated regardless of the account's other Pages projects.A project name restored from the Pages configuration cache is only used when the cache belongs to the currently authenticated account. An account-matching cached name remains on Pages even when the project is missing remotely, preserving the user's recorded Pages intent. After switching accounts, an otherwise unnamed deploy stays on Pages rather than treating a stale cached project name as a new project on the selected account.
Patch Changes
Fix
wrangler d1 execute --localbeing extremely slow with large SQL files or commandsThe local SQL splitter consumed quoted strings and comments character-by-character, re-checking the full accumulated string each time. This made splitting a large quoted value or comment quadratic, so seed files could take tens of seconds to run. The splitter now only inspects a bounded trailing window on each step, making splitting effectively linear. The remote path is unaffected as it imports the file server-side.
Fix
wrangler devrunning the custom build command twice on startup and on every config changeWrangler already runs the custom
build.commandonce before startingwrangler dev, to resolve the Worker's entry point. Whendev.watchwasn't explicitly disabled,BundlerControllerthen unconditionally ran the same build command again the moment it started watching for changes, and repeated this on every subsequent config reload too.For fast build commands this just meant duplicate log output (e.g. a
vite buildvisibly running twice at startup). For slower or stateful build commands, running two builds concurrently against the same output files could corrupt the result or fail outright (for example, non-deterministicwasm-optfailures have been reported for Rust builds).The initial watcher setup now only bundles the output the build command already produced, instead of re-running the command. Real file changes detected by the watcher still re-run the build command as before.
4.129.1
7 Sep 2026Prevent Wrangler from exiting when a process capturing its output closes the pipe.
Wrangler now ignores broken-pipe errors from stdout and stderr while preserving the existing failure behavior for other output errors.
Update bundle size warning thresholds to use uncompressed size instead of gzip size
The compressed script size limits (3 MiB free / 10 MiB paid) have been removed server-side in favor of a single 64 MiB uncompressed limit. The bundle size reporter now compares the uncompressed bundle size against this 64 MiB limit for its color-coded warnings, instead of comparing gzip size against the old 3 MiB compressed limit.
Honor Workers Builds name overrides in
wrangler previewPreview commands now target the Worker name supplied by Workers Builds instead of the name in local Wrangler configuration. This prevents preview builds from failing when the two names differ.
Patch Changes
Prevent Wrangler from exiting when a process capturing its output closes the pipe.
Wrangler now ignores broken-pipe errors from stdout and stderr while preserving the existing failure behavior for other output errors.
Update bundle size warning thresholds to use uncompressed size instead of gzip size
The compressed script size limits (3 MiB free / 10 MiB paid) have been removed server-side in favor of a single 64 MiB uncompressed limit. The bundle size reporter now compares the uncompressed bundle size against this 64 MiB limit for its color-coded warnings, instead of comparing gzip size against the old 3 MiB compressed limit.
Honor Workers Builds name overrides in
wrangler previewPreview commands now target the Worker name supplied by Workers Builds instead of the name in local Wrangler configuration. This prevents preview builds from failing when the two names differ.
wrangler devno longer exits when a request to your Worker fails transientlyPreviously, a transient network failure on a single request — most commonly a request arriving just as an idle internal connection was closed, after roughly five seconds without traffic — could take down the whole dev server with an empty
✘ [ERROR], leaving the port unbound until restarted. In CI test suites, one such failure caused every remaining test to fail with connection errors.wrangler devnow automatically retries the affected request if it is safe to repeat (GET and HEAD requests). If a request still fails, it fails individually — the error is logged with the request method and URL — and the dev server keeps serving.
4.129.0
3 Sep 2026Support gzip compression for JSON Pipelines sinks
Pipelines is in open beta.
wrangler pipelines sinks createand the interactive setup flow now pass the selected JSON compression to the Pipelines API. JSON sinks acceptuncompressedorgzip, while Parquet retains its existing compression options andzstddefault.Add a
--jsonflag to thewrangler workflowscommandsEvery
wrangler workflowscommand now accepts--json, which emits the raw API payload instead of the human-readable rendering. The formatted output remains the default, so existing usage is unaffected:wrangler workflows instances list my-workflow --jsonThe JSON output carries raw values rather than a serialisation of the formatted view: ISO timestamps instead of locale-formatted dates, plain status strings instead of emojified labels, and no presentation-only derived fields.
Tolerate missing permissions during
wrangler deletecleanup checkswrangler deletenow warns and continues when it cannot inspect Worker dependencies or clean up legacy Workers Sites KV namespaces because of missing permissions. The Worker delete request itself still fails normally if the token cannot delete the Worker.
Minor Changes
Support gzip compression for JSON Pipelines sinks
Pipelines is in open beta.
wrangler pipelines sinks createand the interactive setup flow now pass the selected JSON compression to the Pipelines API. JSON sinks acceptuncompressedorgzip, while Parquet retains its existing compression options andzstddefault.Add a
--jsonflag to thewrangler workflowscommandsEvery
wrangler workflowscommand now accepts--json, which emits the raw API payload instead of the human-readable rendering. The formatted output remains the default, so existing usage is unaffected:wrangler workflows instances list my-workflow --jsonThe JSON output carries raw values rather than a serialisation of the formatted view: ISO timestamps instead of locale-formatted dates, plain status strings instead of emojified labels, and no presentation-only derived fields.
Patch Changes
Tolerate missing permissions during
wrangler deletecleanup checkswrangler deletenow warns and continues when it cannot inspect Worker dependencies or clean up legacy Workers Sites KV namespaces because of missing permissions. The Worker delete request itself still fails normally if the token cannot delete the Worker.Tolerate missing resource permissions during resource provisioning
When Wrangler cannot check whether a bound resource exists because the API returns a 403, it now skips automatic provisioning for that resource type and continues the deploy. The deploy may still fail later if the resource is missing.
Fix remote development with static assets for API tokens using granular Worker permissions
Wrangler now creates Workers.dev preview sessions through the Worker-scoped endpoint and derives the preview hostname from the session response. This avoids requiring account-level Workers subdomain access.
4.128.0
1 Sep 2026Move binding utilities into
@cloudflare/workers-utilsBinding conversion, printing, and local-development validation are now exported from
@cloudflare/workers-utilsso they can be shared by Wrangler, the Cloudflare Vite plugin, and other consumers.The corresponding exports have been removed from
@cloudflare/deploy-helpers. Consumers should import them directly from@cloudflare/workers-utilsinstead.Wrangler's
unstable_printBindingsAPI now accepts the bindings and an options object instead of five positional parameters.Add
--date-startand--date-endfilters towrangler workflows instances listYou can now narrow an instance listing to a creation-time window:
wrangler workflows instances list my-workflow --date-start 2026-01-01 --date-end 2026-01-31Either flag can be used independently. Both accept an ISO 8601 date or timestamp and are normalised to UTC before being sent, so a date-only value such as
2026-01-01works as well as a full2026-01-01T13:00:00Z. The bounds are inclusive and compose with the existing--statusfilter.Add query string redaction to Workers observability configuration
Set
observability.redact_query_stringinwrangler.jsonorobservability.redactQueryStringin the experimentalcloudflare.config.tsformat to remove query strings from request URLs in logs and traces.
Minor Changes
Move binding utilities into
@cloudflare/workers-utilsBinding conversion, printing, and local-development validation are now exported from
@cloudflare/workers-utilsso they can be shared by Wrangler, the Cloudflare Vite plugin, and other consumers.The corresponding exports have been removed from
@cloudflare/deploy-helpers. Consumers should import them directly from@cloudflare/workers-utilsinstead.Wrangler's
unstable_printBindingsAPI now accepts the bindings and an options object instead of five positional parameters.Add
--date-startand--date-endfilters towrangler workflows instances listYou can now narrow an instance listing to a creation-time window:
wrangler workflows instances list my-workflow --date-start 2026-01-01 --date-end 2026-01-31Either flag can be used independently. Both accept an ISO 8601 date or timestamp and are normalised to UTC before being sent, so a date-only value such as
2026-01-01works as well as a full2026-01-01T13:00:00Z. The bounds are inclusive and compose with the existing--statusfilter.Add query string redaction to Workers observability configuration
Set
observability.redact_query_stringinwrangler.jsonorobservability.redactQueryStringin the experimentalcloudflare.config.tsformat to remove query strings from request URLs in logs and traces.Include exact raw and gzip-compressed Worker bundle sizes in structured
deployandversion-uploadoutput.
Patch Changes
Reduce the installed bundle sizes of Wrangler and Miniflare
Wrangler now resolves bundled workspace dependencies from source during monorepo builds so unused exports can be removed. Miniflare, its shared CLI and container dependencies now use granular
@cloudflare/workers-utilsentry points instead of loading the package barrel, reducing the raw Wrangler and Miniflare artifacts by 6.16 MiB (31.4%) and 1.06 MiB (22.9%) respectively without changing runtime behavior or installed dependencies.Reduce Wrangler's published package size
Stop including the unused build metafile in the npm package, reducing its unpacked size by approximately 3.1 MiB.
Skip the skills install status lookup when telemetry is disabled
Telemetry events include a
currentAgentSkillsInstalledproperty, and computing it can query the GitHub API. The lookup used to start before the telemetry permission was checked, so users who opted out viaWRANGLER_SEND_METRICS,DO_NOT_TRACK, orsend_metricsin their Wrangler config still triggered network requests on behalf of telemetry. The dispatcher now checks the permission first and only performs the lookup when telemetry is enabled.
4.127.1
28 Aug 2026Only updates a dependency:miniflare 5.20260828.0-alpha
4.127.0
27 Aug 2026Add support for configuring a per-workflow max concurrency limit via
workflows.concurrency.limitin your Wrangler config.The limit is the maximum number of Workflow instances that can run concurrently. It is validated as a positive integer and persisted on deploy; the ceiling is enforced server-side. Concurrency is ignored in local development.
{ "workflows": [ { "binding": "MY_WORKFLOW", "name": "my-workflow", "class_name": "MyWorkflow", "concurrency": { "limit": 10 } } ] }Upload
wrangler previewmodules as multipart form datawrangler previewused to base64 the bundle, its modules, and any sourcemaps into a single JSON request body. Base64 inflates content by a third, so a Worker with a large sourcemap could exceed the API request size limit and fail to deploy.The preview deployment request is now
multipart/form-data. The deployment settings travel in ametadatapart and each module follows as its own part carrying raw bytes, matching howwrangler deployalready uploads a Worker.
Minor Changes
Add support for configuring a per-workflow max concurrency limit via
workflows.concurrency.limitin your Wrangler config.The limit is the maximum number of Workflow instances that can run concurrently. It is validated as a positive integer and persisted on deploy; the ceiling is enforced server-side. Concurrency is ignored in local development.
{ "workflows": [ { "binding": "MY_WORKFLOW", "name": "my-workflow", "class_name": "MyWorkflow", "concurrency": { "limit": 10 } } ] }
Patch Changes
Upload
wrangler previewmodules as multipart form datawrangler previewused to base64 the bundle, its modules, and any sourcemaps into a single JSON request body. Base64 inflates content by a third, so a Worker with a large sourcemap could exceed the API request size limit and fail to deploy.The preview deployment request is now
multipart/form-data. The deployment settings travel in ametadatapart and each module follows as its own part carrying raw bytes, matching howwrangler deployalready uploads a Worker.
4.126.0
25 Aug 2026Add
default_retentionto Workflow bindings for configuring how long instances are retainedWorkflow instances are retained for an account-wide default period after they finish. You can now set a per-Workflow default in your Wrangler configuration, applied to instances that do not specify their own retention:
{ "workflows": [ { "binding": "MY_WORKFLOW", "name": "my-workflow", "class_name": "MyWorkflow", "default_retention": { "success_retention": "3 days", "error_retention": "7 days" } } ] }Each side is optional and accepts either a duration string such as
"3 days"or a whole number of milliseconds. Durations are interpreted by the Workflows API, which also caps them at your account's retention limit.Include a chronological list of handler events in email test harness results, so programmatic local email tests can assert the order in which messages are received, forwarded, replied to, or rejected.
const result = await server.getWorker().email({ from: "sender@example.com", to: "inbox@example.com", raw: [ "From: Sender <sender@example.com>", "To: Inbox <inbox@example.com>", "Message-ID: <test@example.com>", "Subject: Test email", "", "Hello from the test harness", ].join("\r\n"), }); expect(result.events).toEqual([ { type: "received", timestamp: expect.any(String) }, { type: "forward", timestamp: expect.any(String), messageId: expect.any(String), }, { type: "reply", timestamp: expect.any(String), messageId: expect.any(String), }, ]);Add experimental
wrangler hyperdrive planetscale signaturefor provisioning Cloudflare-billed PlanetScale databaseswrangler hyperdrive planetscale signatureprints a signed authorization as JSON, proving to PlanetScale that Cloudflare will be billed for the database you are about to create:npx wrangler hyperdrive planetscale signature | \ pscale database create <name> \ --org <org> \ --engine postgresql \ --cloudflare-billing @- \ --format jsonpscale database createdefaults to Vitess, so pass--engine postgresqlfor a Postgres database, and--format jsonis recommended when the output is consumed by an agent.This requires
pscalev0.313.0 or newer. Wrangler authorizes the Cloudflare billing side only, so your PlanetScale credentials stay between you andpscale.The signature is a cryptographically signed token that authorizes creating a database billed to your Cloudflare account. Treat it as a credential and do not share it. Piping it, as above, is recommended over passing it as a command line argument.
This command is experimental and its interface may change.
Minor Changes
Add
default_retentionto Workflow bindings for configuring how long instances are retainedWorkflow instances are retained for an account-wide default period after they finish. You can now set a per-Workflow default in your Wrangler configuration, applied to instances that do not specify their own retention:
{ "workflows": [ { "binding": "MY_WORKFLOW", "name": "my-workflow", "class_name": "MyWorkflow", "default_retention": { "success_retention": "3 days", "error_retention": "7 days" } } ] }Each side is optional and accepts either a duration string such as
"3 days"or a whole number of milliseconds. Durations are interpreted by the Workflows API, which also caps them at your account's retention limit.Include a chronological list of handler events in email test harness results, so programmatic local email tests can assert the order in which messages are received, forwarded, replied to, or rejected.
const result = await server.getWorker().email({ from: "sender@example.com", to: "inbox@example.com", raw: [ "From: Sender <sender@example.com>", "To: Inbox <inbox@example.com>", "Message-ID: <test@example.com>", "Subject: Test email", "", "Hello from the test harness", ].join("\r\n"), }); expect(result.events).toEqual([ { type: "received", timestamp: expect.any(String) }, { type: "forward", timestamp: expect.any(String), messageId: expect.any(String), }, { type: "reply", timestamp: expect.any(String), messageId: expect.any(String), }, ]);Add experimental
wrangler hyperdrive planetscale signaturefor provisioning Cloudflare-billed PlanetScale databaseswrangler hyperdrive planetscale signatureprints a signed authorization as JSON, proving to PlanetScale that Cloudflare will be billed for the database you are about to create:npx wrangler hyperdrive planetscale signature | \ pscale database create <name> \ --org <org> \ --engine postgresql \ --cloudflare-billing @- \ --format jsonpscale database createdefaults to Vitess, so pass--engine postgresqlfor a Postgres database, and--format jsonis recommended when the output is consumed by an agent.This requires
pscalev0.313.0 or newer. Wrangler authorizes the Cloudflare billing side only, so your PlanetScale credentials stay between you andpscale.The signature is a cryptographically signed token that authorizes creating a database billed to your Cloudflare account. Treat it as a credential and do not share it. Piping it, as above, is recommended over passing it as a command line argument.
This command is experimental and its interface may change.
Enable FUSE-capable local container development
Miniflare now automatically passes the Docker privileges needed for FUSE to local Durable Object containers when using local rootless Docker on Linux with
/dev/fuseavailable, or a local Docker engine on macOS or through WSL where Linux containers run in a VM. This applies to Wrangler, the Cloudflare Vite plugin, and direct Miniflare use.Record the selected mode in the Build Output Specification top-level
config.jsonThe mode a build was produced in is now written to
.cloudflare/output/v0/config.jsonas amodefield, alongside the account and compliance settings.Add pull request metadata to
wrangler previewdeploymentswrangler previewnow detects the pull request associated with the current CI run (GitHub Actions, GitLab CI, CircleCI, and a genericPULL_REQUEST_URL/PR_URL/CHANGE_URLfallback) and attaches it, along with the repository URL, to the preview deployment as annotations (workers/pull_request_number,workers/pull_request_url,workers/repository_url).This is best effort: if no pull request can be detected, nothing changes. When a pull request is detected, its URL is now also shown in the
wrangler previewcommand output.Add pull request title to
wrangler previewdeployment annotationswrangler previewnow also detects the title of the pull/merge request associated with the current CI run (GitHub Actions and GitLab CI, plus a genericPULL_REQUEST_TITLEfallback) and attaches it to the preview deployment as theworkers/pull_request_titleannotation, alongside the existing pull request number/URL, repository URL, and commit SHA annotations.This is best effort: if no pull request title can be detected, nothing changes.
Patch Changes
Prepare autoconfig for multiple configuration targets
Add target-specific configuration output and command detection while preserving Wrangler's existing setup and deployment behavior.
Fix
wrangler login --use-keyringincorrectly reporting thatsecret-toolis missing on LinuxLibsecret's
secret-tooldoes not support--version; it prints usage and exits 2, which Wrangler previously interpreted as unavailable. Wrangler now reports it missing only when launching the executable fails.[private beta]: Explain unavailable Preview URLs afterwrangler previewdeploymentsWhen a Preview deployment has no active URLs, Wrangler now explains how to enable Preview Deployments on workers.dev or a custom domain.
Stop automatically offering to install Cloudflare skills for new users
Wrangler will no longer prompt new users to install Cloudflare skills after commands complete. It will continue to offer updates to skills that Wrangler previously installed.
4.125.0
20 Aug 2026Add
connecttrigger for raw socketsYou can now configure a Worker to receive raw socket connections during
wrangler dev, delivered directly to the Worker'sconnect(socket, env, ctx)handler:{ "connect": [{ "protocol": "tcp", "port": 5432 }] }Each entry opens a listening socket on
127.0.0.1(or the givenaddress) that forwards incoming connections straight to the Worker, bypassing the local dev HTTP entry point. This requires theexperimentalcompatibility flag. Only"tcp"is supported at the moment.@cloudflare/configalso supports declaring this trigger viatriggers.connect(...), which lowers to theconnectfield above:import { defineWorker, triggers } from "@cloudflare/config"; export default defineWorker({ triggers: [ triggers.connect({ protocol: "tcp", port: 5432, address: "127.0.0.1" }), ], });Add container support to worker previews
Worker previews now support containers through a new
previews.containersconfiguration block. Container configuration doesn't inherit, so declare containers explicitly in thepreviewsblock to enable them for previews. This mirrors howpreviews.durable_objectsworks today. Wrangler names each preview container application{worker_name}_{preview_slug}_{class_name}, normalising and shortening the result to what the API accepts. Either change appends a short digest of the composed name, so two names that would otherwise land on one stay distinct. An entry cannot set its ownname, because application names are unique to an account and a fixed name would collide between two previews of the same Worker. A Durable Object class is backed by at most one container application, so the validator rejects two entries that share aclass_name. Wrangler skips container applications bound to Durable Object classes that another Worker implements throughscript_name, because the implementing Worker owns its own container application. A binding is not required: a Durable Object declared throughmigrationsorexportsand reached only overctx.exportscan still back a container. Every entry must setclass_name. Apreviews.containersentry whoseclass_namematches no Durable Object class at all is rejected before the preview deployment is created, so a typo fails loudly instead of producing a preview with no container.Wrangler creates the container applications on
wrangler preview. Deleting a preview tears them down server side, sowrangler preview deletedoesn't remove them.Container build and deploy progress prints to stdout.
wrangler preview --jsonsuppresses wrangler's own output so it doesn't interleave with the payload, and warnings and errors still go to stderr. Docker's build output and the progress spinner write to stdout directly and bypass that suppression, so parse--jsonfrom a non interactive shell, where the spinner is skipped, and prefer a prebuiltimageover a Dockerfile.[private beta]: Create the parent Worker automatically when
wrangler previewtargets one that doesn't exist yetPreviews hang off a parent Worker, so running
wrangler previewbefore the Worker had ever been deployed failed with a raw API error naming the Preview endpoint. Wrangler now offers to create an empty parent Worker and then carries on creating the Preview. The parent uses the same workers.dev and Preview URL settings thatwrangler deploywould resolve, without applying routes or cron triggers. In non-interactive environments, Wrangler creates the Worker without asking.
Minor Changes
Add
connecttrigger for raw socketsYou can now configure a Worker to receive raw socket connections during
wrangler dev, delivered directly to the Worker'sconnect(socket, env, ctx)handler:{ "connect": [{ "protocol": "tcp", "port": 5432 }] }Each entry opens a listening socket on
127.0.0.1(or the givenaddress) that forwards incoming connections straight to the Worker, bypassing the local dev HTTP entry point. This requires theexperimentalcompatibility flag. Only"tcp"is supported at the moment.@cloudflare/configalso supports declaring this trigger viatriggers.connect(...), which lowers to theconnectfield above:import { defineWorker, triggers } from "@cloudflare/config"; export default defineWorker({ triggers: [ triggers.connect({ protocol: "tcp", port: 5432, address: "127.0.0.1" }), ], });Add container support to worker previews
Worker previews now support containers through a new
previews.containersconfiguration block. Container configuration doesn't inherit, so declare containers explicitly in thepreviewsblock to enable them for previews. This mirrors howpreviews.durable_objectsworks today. Wrangler names each preview container application{worker_name}_{preview_slug}_{class_name}, normalising and shortening the result to what the API accepts. Either change appends a short digest of the composed name, so two names that would otherwise land on one stay distinct. An entry cannot set its ownname, because application names are unique to an account and a fixed name would collide between two previews of the same Worker. A Durable Object class is backed by at most one container application, so the validator rejects two entries that share aclass_name. Wrangler skips container applications bound to Durable Object classes that another Worker implements throughscript_name, because the implementing Worker owns its own container application. A binding is not required: a Durable Object declared throughmigrationsorexportsand reached only overctx.exportscan still back a container. Every entry must setclass_name. Apreviews.containersentry whoseclass_namematches no Durable Object class at all is rejected before the preview deployment is created, so a typo fails loudly instead of producing a preview with no container.Wrangler creates the container applications on
wrangler preview. Deleting a preview tears them down server side, sowrangler preview deletedoesn't remove them.Container build and deploy progress prints to stdout.
wrangler preview --jsonsuppresses wrangler's own output so it doesn't interleave with the payload, and warnings and errors still go to stderr. Docker's build output and the progress spinner write to stdout directly and bypass that suppression, so parse--jsonfrom a non interactive shell, where the spinner is skipped, and prefer a prebuiltimageover a Dockerfile.[private beta]: Create the parent Worker automatically when
wrangler previewtargets one that doesn't exist yetPreviews hang off a parent Worker, so running
wrangler previewbefore the Worker had ever been deployed failed with a raw API error naming the Preview endpoint. Wrangler now offers to create an empty parent Worker and then carries on creating the Preview. The parent uses the same workers.dev and Preview URL settings thatwrangler deploywould resolve, without applying routes or cron triggers. In non-interactive environments, Wrangler creates the Worker without asking.Add individual and batch Workflow instance deletion to the runtime and SDK.
WorkflowInstance.delete()deletes one instance. Self-deletion stops the current execution.env.MY_WORKFLOW.deleteBatch(instanceIds)deletes up to 100 instances and returns{ deleted, errors }per input position.wrangler workflows instances delete <name> [id..]deletes instances remotely or with--local; IDs can also come from a JSON array passed with--filename, with a combined limit of 100.
Patch Changes
Fixes
kv bulk putcorrupting binary values written to local KVValues marked
base64: truewere stored incorrectly whenever they contained bytes that do not form valid UTF-8, which covers images, compressed data and most other binary payloads. A Worker reading such a key back underwrangler devgot a different, longer value than the one that was written: a 12 byte PNG header came back as 20 bytes.kv bulk putwrites to local KV by default, so the plain command was the affected one. Remote writes were never affected, and neither were entries withoutbase64or values written withkv key put.Move deploy output writing into shared deploy helpers
Remove unsupported
remoteconfiguration from Workflow bindingsWorkflow bindings no longer accept
remotein configuration, as remote Workflow bindings have never actually been supported.Fix the
--temporaryerror on commands that authenticate more than one timewrangler d1 migrations apply --remote --temporaryfailed with this error:You're already authenticated with Cloudflare, so --temporary can't be used. The failure occurred with no login and with noCLOUDFLARE_API_TOKEN. This command authenticates one time for each statement that it runs. The first authentication makes a temporary preview account. The second authentication read the token of this new account as an earlier login.Wrangler now uses again the temporary account from the same command run. Commands that authenticate more than one time now work as
wrangler deploy --temporaryworks. If real credentials are available,--temporaryis still an error.
4.124.0
18 Aug 2026Allow containers to be attached to a Durable Object from its
exportsentryA container can now be linked to its Durable Object from the export side, using a new
containerfield that names an entry in thecontainersarray. As a resultcontainers.class_nameis now optional — a container that is referenced this way only needs aname:{ "name": "my-worker", "main": "worker.js", "compatibility_date": "2026-07-01", "containers": [ { "name": "my-container", "image": "./Dockerfile", "max_instances": 1 } ], "exports": { "MyContainerDO": { "type": "durable-object", "storage": "sqlite", "container": "my-container" } } }The existing
containers.class_namedirection keeps working and either direction may be used, but the two must agree: a container that names its Durable Object cannot also be claimed by a different one.containeris only valid on livedurable-objectexports (createdandexpecting-transfer) and requiresstorage: "sqlite". Wrangler now also reports an error when:That last case was previously accepted but could never work: workerd attaches a single container per Durable Object namespace, and in local development every container for a class builds into the same image tag, so one silently overwrote the other. If you have two containers on one
class_name, give each its own Durable Object class.Honor
access.devwhen running Workers with@cloudflare/vitest-pool-workers, soctx.access.getIdentity()returns the configured identity just as it does withwrangler dev.Fix
.envloading on Windows leaking stale, differently-cased duplicate keysOn Windows,
wranglerloads.envvalues through a case-insensitiveProxywrapper so lookups likeenv.PATHandenv.Pathresolve to the same value, and this object is assigned directly toprocess.env. When a key was set again under a different casing (e.g. a value in.env.localoverriding one from.envwith different casing), the previous casing was never removed from the underlying object.env.PATH/env.Pathstill returned the correct, latest value, but anything that enumeratesprocess.env—Object.keys,for...in,JSON.stringify, object spread, or a spawned subprocess inheriting the environment — would see both the stale and current key.Duplicate entries no longer appear, so environment variables passed to subprocesses and any code that lists the environment now see only the latest value for each variable.
Minor Changes
Allow containers to be attached to a Durable Object from its
exportsentryA container can now be linked to its Durable Object from the export side, using a new
containerfield that names an entry in thecontainersarray. As a resultcontainers.class_nameis now optional — a container that is referenced this way only needs aname:{ "name": "my-worker", "main": "worker.js", "compatibility_date": "2026-07-01", "containers": [ { "name": "my-container", "image": "./Dockerfile", "max_instances": 1 } ], "exports": { "MyContainerDO": { "type": "durable-object", "storage": "sqlite", "container": "my-container" } } }The existing
containers.class_namedirection keeps working and either direction may be used, but the two must agree: a container that names its Durable Object cannot also be claimed by a different one.containeris only valid on livedurable-objectexports (createdandexpecting-transfer) and requiresstorage: "sqlite". Wrangler now also reports an error when:a
containerreference names a container that does not existtwo Durable Object exports claim the same container
a container and a Durable Object export disagree about which one they are linked to
a container ends up linked to no Durable Object at all
two containers share a
namea container's
class_namenames a Durable Object whosestorageislegacy-kvtwo containers are attached to the same Durable Object
That last case was previously accepted but could never work: workerd attaches a single container per Durable Object namespace, and in local development every container for a class builds into the same image tag, so one silently overwrote the other. If you have two containers on one
class_name, give each its own Durable Object class.
Patch Changes
Honor
access.devwhen running Workers with@cloudflare/vitest-pool-workers, soctx.access.getIdentity()returns the configured identity just as it does withwrangler dev.Fix
.envloading on Windows leaking stale, differently-cased duplicate keysOn Windows,
wranglerloads.envvalues through a case-insensitiveProxywrapper so lookups likeenv.PATHandenv.Pathresolve to the same value, and this object is assigned directly toprocess.env. When a key was set again under a different casing (e.g. a value in.env.localoverriding one from.envwith different casing), the previous casing was never removed from the underlying object.env.PATH/env.Pathstill returned the correct, latest value, but anything that enumeratesprocess.env—Object.keys,for...in,JSON.stringify, object spread, or a spawned subprocess inheriting the environment — would see both the stale and current key.Duplicate entries no longer appear, so environment variables passed to subprocesses and any code that lists the environment now see only the latest value for each variable.
Normalize structural CRLF line endings before sending D1 commands to the remote query API
wrangler d1 migrations apply --remoteandwrangler d1 execute --remote --commandfailed withincomplete input: SQLITE_ERRORwhen the SQL contained CRLF line endings inside a compound statement such as aCREATE TRIGGER ... BEGIN ... END;body. Structural line endings are now normalized to LF before the command is sent to the D1 query API, while CRLF inside quoted values and identifiers remains unchanged.Fixes D1 SQL statements not handling lowercase
ends correctlywrangler d1 executeandwrangler d1 migrations applysplit a SQL file into statements before running them. ABEGINorCASEblock closed with a lowercaseendwas not recognised as closed, so every statement after it was folded into that block instead of being run on its own. SQLite accepts either case, so a file like this applied only the trigger and silently skipped the table:CREATE TRIGGER IF NOT EXISTS update_trigger AFTER UPDATE ON items begin DELETE FROM updates WHERE item_id=old.id; end; CREATE TABLE after_the_trigger (id TEXT PRIMARY KEY);Files written with an uppercase
ENDwere unaffected. Both cases now behave the same.Resolve
--latestto the newest compatibility date supported by the installed runtimewrangler deploy --latestandwrangler versions upload --latestresolved the compatibility date to the current date, andwrangler pages download configdid the same for projects configured to always use the latest compatibility date. Both write that date into a configuration file for subsequent commands to use, so a date that the installedworkerddid not yet support left the project unable to runwrangler dev.These now resolve to the latest compatibility date supported by this version of Wrangler, which is the release date of the
workerdit ships with.Fix spurious
Trailing comma jsonc(519)warnings forwrangler.jsoncin VS Code 1.131+Trailing commas in
wrangler.jsoncfiles that reference Wrangler's JSON schema are no longer reported as errors by recent versions of VS Code. Wrangler always accepted these files; only the editor warning was wrong.Respect
CLOUDFLARE_ACCOUNT_IDinwrangler pages project list,createanddeleteThese three commands could target a previously used account even when
CLOUDFLARE_ACCOUNT_IDwas set, failing withAuthentication error [code: 10000]in setups with more than one account. They now use the account named byCLOUDFLARE_ACCOUNT_ID, matching the rest ofwrangler pages. When the variable is unset, the previously used account is still selected, as before.Fix
wrangler preview base-configcommands showing an inheritedscriptpositionalUse a fixed default compatibility date rather than the current date
When no compatibility date was set, Wrangler, C3 and the Vitest pool all defaulted to the current date.
workerdonly accepts a compatibility date up to 7 days beyond its own release, so whenever aworkerdrelease was delayed the default could get ahead of the runtime that had been installed, and local development would fail to start.The default is now fixed at the release date of the
workerdversion that ships with each release, which leaves a week of headroom and updates asworkerdis upgraded.@cloudflare/vite-pluginpreviously inlined the date at which it was built. It now shares the same default.Prevent date-enabled Node.js compatibility from adding conflicting globals to generated runtime types
Runtime type generation now treats Node.js compatibility enabled by a compatibility date the same way as an explicit
nodejs_compatflag. Node.js globals continue to come from@types/nodeinstead of being generated asanydeclarations that override those types.Use the FedRAMP High managed container registry when Wrangler targets the FedRAMP High compliance region
Container builds, pushes, deployments, image commands, and local development now select the corresponding production or staging FedRAMP registry and API from either
compliance_regionorCLOUDFLARE_COMPLIANCE_REGION.Enable the new configuration format in the
cf-wranglerdev delegateProjects started through
cf devnow loadcloudflare.config.tsand optionalwrangler.config.ts, matching the configuration used by the delegate's build path.
4.123.0
13 Aug 2026Add local dev simulation for Cloudflare Access
ctx.access.getIdentity()You can now configure a mock Cloudflare Access identity in
wrangler.jsonso thatctx.access.getIdentity()returns it during local development.// wrangler.json { "access": { "dev": { "aud": "my-app-aud-tag", "identity": { "email": "user@example.com", "name": "Test User" } } } }[private beta]: Updates the
--ignore-defaultsflag to--ignore-base-configonwrangler previewcommands.--ignore-base-confignow only takes effect on Preview creation, rather than on each deployment, since Preview base configuration is now copy-on-create rather than inherit-on-deploy.Add automatic update prompts for out-of-date Cloudflare agent skills
When Cloudflare skills were previously installed by Wrangler and the upstream
cloudflare/skillsrepository has newer content, Wrangler now offers to update them after eligible commands complete.To reduce prompt fatigue, the update check only runs once a month (30 days since the last install or update). Declining suppresses the prompt until the next upstream change.
When declining an update, Wrangler offers the option to permanently disable future update prompts. This preference is stored globally in
~/.wrangler/agents-skills-install.jsonc. TheWRANGLER_NO_SKILLS_UPDATE_PROMPTS=trueenvironment variable can also be used to suppress prompts. The--install-skillsflag remains available regardless of these settings.
Minor Changes
Add local dev simulation for Cloudflare Access
ctx.access.getIdentity()You can now configure a mock Cloudflare Access identity in
wrangler.jsonso thatctx.access.getIdentity()returns it during local development.// wrangler.json { "access": { "dev": { "aud": "my-app-aud-tag", "identity": { "email": "user@example.com", "name": "Test User" } } } }[private beta]: Updates the
--ignore-defaultsflag to--ignore-base-configonwrangler previewcommands.--ignore-base-confignow only takes effect on Preview creation, rather than on each deployment, since Preview base configuration is now copy-on-create rather than inherit-on-deploy.Add automatic update prompts for out-of-date Cloudflare agent skills
When Cloudflare skills were previously installed by Wrangler and the upstream
cloudflare/skillsrepository has newer content, Wrangler now offers to update them after eligible commands complete.To reduce prompt fatigue, the update check only runs once a month (30 days since the last install or update). Declining suppresses the prompt until the next upstream change.
When declining an update, Wrangler offers the option to permanently disable future update prompts. This preference is stored globally in
~/.wrangler/agents-skills-install.jsonc. TheWRANGLER_NO_SKILLS_UPDATE_PROMPTS=trueenvironment variable can also be used to suppress prompts. The--install-skillsflag remains available regardless of these settings.
4.122.0
12 Aug 2026Detect Node.js compatibility from the compatibility date, now that
nodejs_compatis enabled by defaultAs of compatibility date
2026-08-04, workerd enables thenodejs_compatandnodejs_compat_v2compatibility flags by default. Previously these tools only treated Node.js compatibility as enabled when one of those flags was listed explicitly, so a Worker on a compatibility date of2026-08-04or later without the flag would get Node.js APIs from the runtime but no Node.js polyfills from the bundler, andprocess.envcould be substituted with an empty object at build time. They now resolve these flags the same way workerd does, and honourno_nodejs_compatto opt out.To keep Node.js compatibility switched off on a newer compatibility date, specify both
no_nodejs_compatandno_nodejs_compat_v2, since each flag has its own default.@cloudflare/vitest-pool-workersneedsnodejs_compat_v2for its own test runner, so it continues to override a project that opts out of it. On a compatibility date that enables the flag anyway, it now drops the opt-out rather than adding the flag back, which workerd would reject — previously this stopped such a project from running any tests at all.wrangler typesalso no longer attributes its@types/nodesuggestion to "thenodejs_compatflag", which it can now make for Workers that do not set the flag at all.Ignore a
nodejs_compatcompatibility flag that the compatibility date already enablesworkerd rejects a compatibility flag that its compatibility date enables by default, so a Worker configured with both a compatibility date of
2026-08-04or later andnodejs_compatfailed to start locally with "The compatibility flag nodejs_compat became the default as of 2026-08-04 so does not need to be specified anymore".The redundant
nodejs_compatandnodejs_compat_v2flags are now dropped when starting the runtime, which has no effect on the resulting Worker because the compatibility date enables both anyway.no_nodejs_compatandno_nodejs_compat_v2still switch Node.js compatibility off, and a flag specified alongside its own opt-out is left alone so that workerd still reports those as contradictory.Stop adding a redundant
nodejs_compatflag to generated Wrangler configurationscreate-cloudflareandwrangler setupwrite today's date as thecompatibility_date, and from2026-08-04that already enablesnodejs_compat. Adding the flag as well made the generated project fail to start with "The compatibility flag nodejs_compat became the default as of 2026-08-04 so does not need to be specified anymore", so the flag is now only added for earlier compatibility dates.create-cloudflarealso removes the flag when a template, or a framework's own scaffolder, already wrote it into a configuration that ends up using such a compatibility date, and still installs@types/nodefor these projects even though there is no longer a flag to detect them by.wrangler setupdoes the same for awrangler.json(c)that is already in the project: it writes today's date over whatever date that configuration was written for, so anodejs_compatit finds there is removed as part of writing the file.
Minor Changes
Detect Node.js compatibility from the compatibility date, now that
nodejs_compatis enabled by defaultAs of compatibility date
2026-08-04, workerd enables thenodejs_compatandnodejs_compat_v2compatibility flags by default. Previously these tools only treated Node.js compatibility as enabled when one of those flags was listed explicitly, so a Worker on a compatibility date of2026-08-04or later without the flag would get Node.js APIs from the runtime but no Node.js polyfills from the bundler, andprocess.envcould be substituted with an empty object at build time. They now resolve these flags the same way workerd does, and honourno_nodejs_compatto opt out.To keep Node.js compatibility switched off on a newer compatibility date, specify both
no_nodejs_compatandno_nodejs_compat_v2, since each flag has its own default.@cloudflare/vitest-pool-workersneedsnodejs_compat_v2for its own test runner, so it continues to override a project that opts out of it. On a compatibility date that enables the flag anyway, it now drops the opt-out rather than adding the flag back, which workerd would reject — previously this stopped such a project from running any tests at all.wrangler typesalso no longer attributes its@types/nodesuggestion to "thenodejs_compatflag", which it can now make for Workers that do not set the flag at all.
Patch Changes
Ignore a
nodejs_compatcompatibility flag that the compatibility date already enablesworkerd rejects a compatibility flag that its compatibility date enables by default, so a Worker configured with both a compatibility date of
2026-08-04or later andnodejs_compatfailed to start locally with "The compatibility flag nodejs_compat became the default as of 2026-08-04 so does not need to be specified anymore".The redundant
nodejs_compatandnodejs_compat_v2flags are now dropped when starting the runtime, which has no effect on the resulting Worker because the compatibility date enables both anyway.no_nodejs_compatandno_nodejs_compat_v2still switch Node.js compatibility off, and a flag specified alongside its own opt-out is left alone so that workerd still reports those as contradictory.Stop adding a redundant
nodejs_compatflag to generated Wrangler configurationscreate-cloudflareandwrangler setupwrite today's date as thecompatibility_date, and from2026-08-04that already enablesnodejs_compat. Adding the flag as well made the generated project fail to start with "The compatibility flag nodejs_compat became the default as of 2026-08-04 so does not need to be specified anymore", so the flag is now only added for earlier compatibility dates.create-cloudflarealso removes the flag when a template, or a framework's own scaffolder, already wrote it into a configuration that ends up using such a compatibility date, and still installs@types/nodefor these projects even though there is no longer a flag to detect them by.wrangler setupdoes the same for awrangler.json(c)that is already in the project: it writes today's date over whatever date that configuration was written for, so anodejs_compatit finds there is removed as part of writing the file.Fix remote binding sessions reusing stale binding configurations
Starting a new remote bindings session that reuses a Worker name no longer picks up the bindings from a previous session, which could cause
Binding "..." not founderrors.
4.121.0
11 Aug 2026Add Preview base config secret commands
Wrangler now manages Worker Preview base config secrets with
wrangler preview base-config secret put,delete,list, andbulk. These commands update the Worker'spreviews_base_config.env, keeping shared defaults scoped to all of that Worker's Previews.wrangler preview base-config secret listreads from the Worker's Preview base config and prints secret names with values masked.wrangler preview base-config secret bulkdeletes a secret when its value isnull, matchingwrangler secret bulk.Allow Wrangler projects to build a Worker once and reuse it in
createTestHarness()Build the Worker once:
wrangler deploy --dry-run --outdir ./worker-output
Then reuse the emitted Worker during test harness startup and reset:
const server = createTestHarness({ workers: [ { configPath: "./wrangler.jsonc", prebuiltWorkerDir: "./worker-output", }, ], });Add
email.sendingas an event subscription source for queueswrangler queues subscription createnow accepts--source email.sendingalongside two new flags,--zone-idand--domain, which identify the zone and the sending domain (zone apex or a verified subdomain) to subscribe to. Both flags are required for this source. The subscription's resource is displayed as the sending domain inwrangler queues subscription get.
Minor Changes
Add Preview base config secret commands
Wrangler now manages Worker Preview base config secrets with
wrangler preview base-config secret put,delete,list, andbulk. These commands update the Worker'spreviews_base_config.env, keeping shared defaults scoped to all of that Worker's Previews.wrangler preview base-config secret listreads from the Worker's Preview base config and prints secret names with values masked.wrangler preview base-config secret bulkdeletes a secret when its value isnull, matchingwrangler secret bulk.Allow Wrangler projects to build a Worker once and reuse it in
createTestHarness()Build the Worker once:
wrangler deploy --dry-run --outdir ./worker-output
Then reuse the emitted Worker during test harness startup and reset:
const server = createTestHarness({ workers: [ { configPath: "./wrangler.jsonc", prebuiltWorkerDir: "./worker-output", }, ], });Add
email.sendingas an event subscription source for queueswrangler queues subscription createnow accepts--source email.sendingalongside two new flags,--zone-idand--domain, which identify the zone and the sending domain (zone apex or a verified subdomain) to subscribe to. Both flags are required for this source. The subscription's resource is displayed as the sending domain inwrangler queues subscription get.Add US jurisdiction support to
wrangler d1 createYou can now create a D1 database in the US jurisdiction with
wrangler d1 create <name> --jurisdiction us. The new jurisdiction is also listed in the command's help output.Use Preview deployment PATCH APIs for Preview secret commands
Wrangler now updates Worker Preview secrets by patching the named Preview's latest deployment instead of patching the Worker's Previews settings. This keeps secret changes scoped to one Preview, avoids affecting production or other Previews, and creates a new Preview deployment that goes live at 100% immediately.
wrangler preview secret listnow reads from the named Preview's latest deployment and prints secret names with values masked.wrangler preview secret bulknow deletes a secret when its value isnull, matchingwrangler secret bulk.Honor
DO_NOT_TRACK=1as a telemetry opt-outWrangler now disables telemetry when
DO_NOT_TRACK=1is set, regardless of other telemetry settings.
Patch Changes
Compact
wrangler previewdeployment success outputwrangler previewnow prints a concise success summary with the Preview name, Preview URL, deployment ID, and Deployment URL instead of the previous box-art settings summary.Fetch script metadata directly instead of listing all scripts
When resolving Durable Object migrations, fetch the specific script's service metadata via
/workers/services/{name}instead of listing all scripts in the account via/workers/scripts. This avoids downloading metadata for every Worker in the account just to find one script's migration tag.Fix
wrangler devcommands crashing withNo such module "wrangler:modules-watch"when"no_bundle": trueRunning
wrangler devorwrangler pages devwith bundling disabled ("no_bundle": trueinwrangler.json, or the--no-bundleflag) no longer crashes at startup withUncaught Error: No such module "wrangler:modules-watch". Live reloading on file changes continues to work as before.
4.120.1
10 Aug 2026Update local development for Miniflare's config-based options
Wrangler now converts the Miniflare options it creates for local development to Miniflare's config-based
workersshape.Users should not expect to notice any changes.
Patch Changes
Update local development for Miniflare's config-based options
Wrangler now converts the Miniflare options it creates for local development to Miniflare's config-based
workersshape.Users should not expect to notice any changes.
4.120.0
7 Aug 2026Adds the ability to find container instances by exact ID or name
wrangler containers instances <application_id> --search <instance_id_or_name>now searches every page and returns exact matches in human-readable or JSON output. JSON returns a top-level array, including an empty array when there is no match, while human-readable output prints a no-match message. If multiple instances have the same exact name, every matching instance is returned.Add explicit pagination to container instance JSON output
Use
wrangler containers instances <application_id> --json --per-page <size>to return one page with machine-readableresult_info, then pass itsnext_page_tokento--page-tokento retrieve the next page. Plain--jsonremains backward-compatible: it requests the complete list and returns the existing top-level array.Cut the per-request cost of local observability capture
Every tail event was written to the trace store as its own Durable Object call, so a request paid two or three round-trips per span. On a module-heavy app under the Vite plugin that dominated dev request latency. Rows are now buffered and written in batches, taking a request from roughly thirty calls to three.
Work in progress still shows up as it happens: the root span is written immediately, console logs and exceptions as they arrive, and a span's completion is written on the next event once 100ms has passed. An invocation that goes completely quiet writes nothing further until it ends, since the flush is driven by tail events rather than a timer.
The Vite plugin's own router, asset and proxy workers are also no longer captured. Their traces were noise the Observability views already hid, and skipping them cuts the spans recorded per request — a side benefit being that a trace's root is now your Worker rather than
__router-worker__.
Minor Changes
Adds the ability to find container instances by exact ID or name
wrangler containers instances <application_id> --search <instance_id_or_name>now searches every page and returns exact matches in human-readable or JSON output. JSON returns a top-level array, including an empty array when there is no match, while human-readable output prints a no-match message. If multiple instances have the same exact name, every matching instance is returned.Add explicit pagination to container instance JSON output
Use
wrangler containers instances <application_id> --json --per-page <size>to return one page with machine-readableresult_info, then pass itsnext_page_tokento--page-tokento retrieve the next page. Plain--jsonremains backward-compatible: it requests the complete list and returns the existing top-level array.
Patch Changes
Cut the per-request cost of local observability capture
Every tail event was written to the trace store as its own Durable Object call, so a request paid two or three round-trips per span. On a module-heavy app under the Vite plugin that dominated dev request latency. Rows are now buffered and written in batches, taking a request from roughly thirty calls to three.
Work in progress still shows up as it happens: the root span is written immediately, console logs and exceptions as they arrive, and a span's completion is written on the next event once 100ms has passed. An invocation that goes completely quiet writes nothing further until it ends, since the flush is driven by tail events rather than a timer.
The Vite plugin's own router, asset and proxy workers are also no longer captured. Their traces were noise the Observability views already hid, and skipping them cuts the spans recorded per request — a side benefit being that a trace's root is now your Worker rather than
__router-worker__.
4.119.0
5 Aug 2026Add
--parse-typeflag towrangler ai-search createwrangler ai-search createnow accepts--parse-typeto control how a website data source discovers URLs.sitemap(the default) reads XML sitemaps;discoverfollows links recursively.Previously the parse type could only be chosen through the interactive wizard, which was skipped whenever
--sourcewas supplied — so it was impossible to create adiscoverinstance from a script.wrangler ai-search create my-instance \ --type web-crawler \ --source https://example.com \ --parse-type discover
The interactive wizard now offers
DiscoveralongsideSitemap.--parse-typeis only valid with--type web-crawler; passing it with--type builtinor--type r2is rejected, since the API stores the value for those source types but never reads it. When the flag is omitted in non-interactive mode the field is left unset and the API default (sitemap) applies.Improve the Local Explorer's Observability views
console.logmessages now render the way the console would (JSON-encoded strings are unwrapped and multi-argument logs are joined), traces and events can be looked up by trace or span id from the search bar, and an event's "View trace" button jumps to the exact invocation that emitted it — even when a trace_id spans several invocations (e.g. a subrequest or self fetch).Add support for OAuth 2.0 Device Authorization Grant to
wrangler loginRun
wrangler login --deviceto authenticate without a local callback server. Useful in containers, remote SSH sessions, Codespaces, and any other environment wherelocalhost:8976is unreachable from your browser.The new flow:
The verification URL is supplied by the authorization server, so it is rejected unless it is an
httpsURL on the same auth domain the device code was requested from — it is never printed or opened otherwise.--callback-hostand--callback-portcannot be combined with--device, since this flow does not start a local callback server.
Minor Changes
Add
--parse-typeflag towrangler ai-search createwrangler ai-search createnow accepts--parse-typeto control how a website data source discovers URLs.sitemap(the default) reads XML sitemaps;discoverfollows links recursively.Previously the parse type could only be chosen through the interactive wizard, which was skipped whenever
--sourcewas supplied — so it was impossible to create adiscoverinstance from a script.wrangler ai-search create my-instance \ --type web-crawler \ --source https://example.com \ --parse-type discover
The interactive wizard now offers
DiscoveralongsideSitemap.--parse-typeis only valid with--type web-crawler; passing it with--type builtinor--type r2is rejected, since the API stores the value for those source types but never reads it. When the flag is omitted in non-interactive mode the field is left unset and the API default (sitemap) applies.Improve the Local Explorer's Observability views
console.logmessages now render the way the console would (JSON-encoded strings are unwrapped and multi-argument logs are joined), traces and events can be looked up by trace or span id from the search bar, and an event's "View trace" button jumps to the exact invocation that emitted it — even when a trace_id spans several invocations (e.g. a subrequest or self fetch).Add support for OAuth 2.0 Device Authorization Grant to
wrangler loginRun
wrangler login --deviceto authenticate without a local callback server. Useful in containers, remote SSH sessions, Codespaces, and any other environment wherelocalhost:8976is unreachable from your browser.The new flow:
prints the verification URL and user code to the terminal,
attempts to open the verification URL in your default browser automatically (suppressed via
--browser=false),and polls the token endpoint until you approve the request (with a 5-minute hard cap).
The verification URL is supplied by the authorization server, so it is rejected unless it is an
httpsURL on the same auth domain the device code was requested from — it is never printed or opened otherwise.--callback-hostand--callback-portcannot be combined with--device, since this flow does not start a local callback server.
4.118.0
31 Jul 2026Add
--jsonflag towrangler containers infofor consistent JSON output with sibling commandslistandinstancesEnable local observability capture by default in dev
wrangler devand the Vite plugin now capture request traces and console logs into the Local Explorer's Observability tab out of the box — previously this was opt-in behindX_LOCAL_OBSERVABILITY=true. SetX_LOCAL_OBSERVABILITY=falseto opt out (for example if the extra per-worker collector/streaming-tail services cause trouble in a multi-process dev-registry setup).Add additional triggers to Workflows
Workers can now declaratively start a locally defined Workflow. Configure event subscriptions under
triggers.events; Wrangler validates each target and updates the script's event triggers during deployment.{ "triggers": { "events": [ { "type": "cf.artifacts.repo.pushed", "filter": { "namespace": "my-namespace", "repo_name": "my-repo" }, "targets": [ { "type": "workflow", "workflow_name": "my-workflow" } ] } ] } }
Minor Changes
Add
--jsonflag towrangler containers infofor consistent JSON output with sibling commandslistandinstancesEnable local observability capture by default in dev
wrangler devand the Vite plugin now capture request traces and console logs into the Local Explorer's Observability tab out of the box — previously this was opt-in behindX_LOCAL_OBSERVABILITY=true. SetX_LOCAL_OBSERVABILITY=falseto opt out (for example if the extra per-worker collector/streaming-tail services cause trouble in a multi-process dev-registry setup).Add additional triggers to Workflows
Workers can now declaratively start a locally defined Workflow. Configure event subscriptions under
triggers.events; Wrangler validates each target and updates the script's event triggers during deployment.{ "triggers": { "events": [ { "type": "cf.artifacts.repo.pushed", "filter": { "namespace": "my-namespace", "repo_name": "my-repo" }, "targets": [ { "type": "workflow", "workflow_name": "my-workflow" } ] } ] } }
Patch Changes
Fix
jsx_fragmentbeing ignored whenwrangler devruns a custom buildIf your project uses a custom build and sets both
jsx_factoryandjsx_fragment,wrangler devused yourjsx_factoryvalue for JSX fragments as well, so fragments compiled incorrectly. Yourjsx_fragmentvalue is now used.Stop
wrangler devstarting new work after you stop it or it reloadsStopping
wrangler dev, or having it reload after a configuration change, could still leave it starting work for the state it had just left behind: your custom build command could run once more after dev had stopped, a change to a file in your assets directory could be reported against configuration that had already been replaced, and in some cases the process could stay alive instead of exiting.That work is now discarded, so stopping or reloading
wrangler devleaves nothing running behind it.Stop
wrangler devfrom running custom builds concurrentlyWhen several watched files changed at once — for example during a
git pullor a "save all" —wrangler devstarted a custom build for every file that changed, so multiple copies of your build command ran at the same time and fought over the same output files.A burst of file changes now results in a single build, and a build only starts once the previous one has finished.
Report a clear error for account IDs that can't be used in a Cloudflare API request
Account IDs are substituted straight into Cloudflare API URL paths, so a value containing non-ASCII characters previously failed deep inside the request layer with an opaque
Cannot convert argument to a ByteStringerror that gave no hint about which setting was at fault. Account IDs read fromCLOUDFLARE_ACCOUNT_IDand from theaccount_idconfiguration field are now validated up front, and an invalid value fails with a message naming both the offending value and where it came from.
4.117.0
31 Jul 2026- removed
Remove
containerEnginefrom the worker options returned byunstable_getMiniflareWorkerOptionsunstable_getMiniflareWorkerOptionsno longer includescontainerEnginein the returnedworkerOptions, since the container engine is a Miniflare instance-wide setting rather than a per-worker one. Callers that build a Miniflare instance from these options should setcontainerEngineat the top level instead. Rewrite local testing paths (
/cdn-cgi/*)Miniflare v5 moved its internal local testing endpoints to
/cdn-cgi/local/*(and/__cf_local/*for endpoints that must remain reachable over tunnels) to prevent any potential collision with production routes.wrangler devand the Vite plugin now transparently rewrite the old paths to the new ones, meaning you can continue to use the old paths without issue.These are the new paths:
Minor Changes
- removed
Remove
containerEnginefrom the worker options returned byunstable_getMiniflareWorkerOptionsunstable_getMiniflareWorkerOptionsno longer includescontainerEnginein the returnedworkerOptions, since the container engine is a Miniflare instance-wide setting rather than a per-worker one. Callers that build a Miniflare instance from these options should setcontainerEngineat the top level instead.
Patch Changes
Rewrite local testing paths (
/cdn-cgi/*)Miniflare v5 moved its internal local testing endpoints to
/cdn-cgi/local/*(and/__cf_local/*for endpoints that must remain reachable over tunnels) to prevent any potential collision with production routes.wrangler devand the Vite plugin now transparently rewrite the old paths to the new ones, meaning you can continue to use the old paths without issue.These are the new paths:
/cdn-cgi/handler/scheduled→/cdn-cgi/local/scheduled/cdn-cgi/handler/email→/cdn-cgi/local/email/cdn-cgi/explorer/*→/cdn-cgi/local/explorer/*/cdn-cgi/mf/scheduled→/cdn-cgi/local/scheduled(Note/cdn-cgi/mf/scheduledis already deprecated)/cdn-cgi/mf/stream/*→/__cf_local/stream/*/cdn-cgi/mf/imagedelivery/*→/__cf_local/imagedelivery/*
4.116.0
30 Jul 2026Avoid Worker and workers.dev naming prompts in agent-driven deploys
Wrangler now derives the Worker name from the project and automatically registers the same project-derived workers.dev account subdomain on a first deploy when running in a detected agent environment. The deploy output explains how to change both names.
The experimental build output directory now includes the Worker's configuration at
.cloudflare/output/v0/workers/default/config.jsoninstead of.cloudflare/output/v0/workers/<worker-name>/worker.config.jsonGraduate
wrangler check startupfrom alpha and show bundle size and a local timing summaryThe command no longer prints an alpha warning. It now reports its local profile window, sampled active, garbage collection, and idle time alongside the raw and compressed bundle sizes. The existing measurement warning continues to distinguish these local measurements from startup time measured on Cloudflare.
Minor Changes
Avoid Worker and workers.dev naming prompts in agent-driven deploys
Wrangler now derives the Worker name from the project and automatically registers the same project-derived workers.dev account subdomain on a first deploy when running in a detected agent environment. The deploy output explains how to change both names.
The experimental build output directory now includes the Worker's configuration at
.cloudflare/output/v0/workers/default/config.jsoninstead of.cloudflare/output/v0/workers/<worker-name>/worker.config.jsonGraduate
wrangler check startupfrom alpha and show bundle size and a local timing summaryThe command no longer prints an alpha warning. It now reports its local profile window, sampled active, garbage collection, and idle time alongside the raw and compressed bundle sizes. The existing measurement warning continues to distinguish these local measurements from startup time measured on Cloudflare.
Add support for dispatching email handlers with
createTestHarnessYou can now call
server.getWorker().email({ from, to, raw })to dispatch directly to a Worker'semail()handler and inspect its outcome, rejection reason, forwarded messages, and replies.const result = await server.getWorker().email({ from: "sender@example.com", to: "inbox@example.com", raw: [ "From: Sender <sender@example.com>", "To: Inbox <inbox@example.com>", "Message-ID: <test@example.com>", "Subject: Test email", "", "Hello from the test harness", ].join("\r\n"), }); expect(result).toMatchObject({ outcome: "ok", forwards: [{ recipient: "archive@example.com" }], replies: [ { sender: "inbox@example.com", raw: expect.stringContaining("Thanks for your email"), }, ], });
Patch Changes
Fix ctrl+c not being able to interrupt wrangler while waiting for Cloudflare Access authorization
When a domain is behind Cloudflare Access (for example during remote bindings startup), wrangler runs
cloudflared access login, which only returns once the user completes the authorization flow in the browser. This was invoked synchronously, blocking Node's event loop, so wrangler could not react to ctrl+c (or anything else) until the authorization completed — abandoning the browser flow left a hung wrangler process that had to be killed externally.cloudflaredis now spawned asynchronously, keeping wrangler responsive while it waits. The remote runtime passes its abort signal through to the spawn, so tearing down the session kills a still-pendingcloudflaredimmediately, with process exit as a last-resort cleanup.Include the local observability query endpoint in the agent-facing Local Explorer hint
The hint
wrangler devprints for AI-agent sessions now listsPOST /cdn-cgi/explorer/api/local/observability/query, so agents can discover the read-only SQL endpoint for captured request traces and console logs (thespansandlogstables) alongside the existing binding and storage routes.Improve the agent-facing Local Explorer hint for the observability query endpoint
When a
wrangler devsession is detected as running inside an AI agent, the hint forPOST /local/observability/querynow explains that the endpoint takes a read-only SQL query (SELECT/WITH only) over the capturedspansandlogstables, notes thatattributesis JSON (read viajson(attributes)), and includes a copy-pasteablecurlexample. The full OpenAPI schema is demoted to a last-resort footer so agents reach for the small, actionable example first instead of fetching the large schema.Fix
wrangler triggers deployto use Vite-generated redirected configurationThe command now reads
.wrangler/deploy/config.json, matchingwrangler deployandwrangler versions upload, so generated Worker names and trigger settings are applied.
4.115.0
28 Jul 2026Add hidden
--jurisdictionoption towrangler kv namespace createfor internal testingThis option creates a KV namespace within a specific jurisdiction (for example
us,eu, orfedramp), backing it with jurisdiction-scoped storage. It is experimental and currently gated to allow-listed accounts, so it is hidden from--helpuntil the feature is generally available.Add experimental
local_dev.experimental_s3_credentialstor2_bucketsconfigWhen set, the R2 bucket is served over a local S3-compatible API at
/cdn-cgi/local/r2/s3/<bucket-id>during local development, authenticated with the configured AWS SigV4 credentials.<bucket-id>is the bucket'sbucket_name, or the binding name ifbucket_nameis not set:{ "r2_buckets": [ { "binding": "BUCKET", "bucket_name": "my-bucket", "local_dev": { "experimental_s3_credentials": { "accessKeyId": "local-access-key-id", "secretAccessKey": "local-secret-access-key" } } } ] }Respect and surface the
Retry-Afterheader on Cloudflare API responsesPreviously, if a Wrangler command (e.g.
wrangler versions upload,wrangler deploy) hit the Cloudflare API's rate limit, the resulting error gave no indication of how long to wait before trying again, and 429 responses weren't retried at all (only5xxerrors were, with a fixed linear backoff).Now:
APIError.isRetryable()is unchanged (still5xxonly);retryOnAPIFailure()separately retries 429s.retryAfterMs, when present, is honoured for any retried error, not just 429s.retryAfterMsis also now populated onAPIErrors raised from direct R2 object requests, the Browser Rendering API, and errors surfaced from commands using the officialcloudflareSDK client.
Minor Changes
Add hidden
--jurisdictionoption towrangler kv namespace createfor internal testingThis option creates a KV namespace within a specific jurisdiction (for example
us,eu, orfedramp), backing it with jurisdiction-scoped storage. It is experimental and currently gated to allow-listed accounts, so it is hidden from--helpuntil the feature is generally available.Add experimental
local_dev.experimental_s3_credentialstor2_bucketsconfigWhen set, the R2 bucket is served over a local S3-compatible API at
/cdn-cgi/local/r2/s3/<bucket-id>during local development, authenticated with the configured AWS SigV4 credentials.<bucket-id>is the bucket'sbucket_name, or the binding name ifbucket_nameis not set:{ "r2_buckets": [ { "binding": "BUCKET", "bucket_name": "my-bucket", "local_dev": { "experimental_s3_credentials": { "accessKeyId": "local-access-key-id", "secretAccessKey": "local-secret-access-key" } } } ] }Respect and surface the
Retry-Afterheader on Cloudflare API responsesPreviously, if a Wrangler command (e.g.
wrangler versions upload,wrangler deploy) hit the Cloudflare API's rate limit, the resulting error gave no indication of how long to wait before trying again, and 429 responses weren't retried at all (only5xxerrors were, with a fixed linear backoff).Now:
429 Too Many Requestsresponses are automatically retried, alongside the existing5xxretry behaviour.If a retried response includes a
Retry-Afterheader, Wrangler waits for that duration instead of the default backoff, and logs a message indicating how long it's waiting. To avoid blocking for an excessive amount of time, waits longer than 60 seconds fail fast instead — the surfacedRetry-Aftervalue lets the caller schedule its own retry.If a retryable error is ultimately surfaced to the user (e.g. because retries were exhausted), the error message includes a note with the
Retry-Afterduration, and thecommand-failedentry written to the Wrangler output file (WRANGLER_OUTPUT_FILE_PATH/WRANGLER_OUTPUT_FILE_DIRECTORY) gains aretry_after_msfield. This lets scripts and CI/CD pipelines calling Wrangler repeatedly (for example,wrangler versions uploadon every commit) read the wait duration directly instead of regex-parsing stderr.
APIError.isRetryable()is unchanged (still5xxonly);retryOnAPIFailure()separately retries 429s.retryAfterMs, when present, is honoured for any retried error, not just 429s.retryAfterMsis also now populated onAPIErrors raised from direct R2 object requests, the Browser Rendering API, and errors surfaced from commands using the officialcloudflareSDK client.Support
connect()on remote VPC Network and VPC Service bindings in local developmentRemote VPC Network and VPC Service bindings previously only supported HTTP and JSRPC, so calling
binding.connect(address)against a private TCP service (for example a database) failed in local dev withIncoming CONNECT on a worker not supported. Raw TCP connections through remote VPC Network and VPC Service bindings now work in local development.This feature is experimental. Existing HTTP and JSRPC usage of remote VPC Network and VPC Service bindings is unaffected, and no new configuration is required.
Patch Changes
Color Email Routing plan change markers
Wrangler now highlights additions in green, updates in yellow, and deletions and conflicts in red so Email Routing deployment plans are easier to scan before confirmation.
Apply Email Routing changes across independent zones concurrently
Wrangler now limits concurrent zone updates while preserving the Email Routing plan order within each zone. Deployments that configure addresses across multiple zones complete faster without breaking delete-before-add transitions at a zone's rule limit.
Fix
wrangler cloudchamber curlmangling header values that contain a colonHeader values were split on every colon and only the segment between the first and second was sent, so
--header location:https://example.com/xarrived ashttps. Headers are now split on the first colon only. A header that is not in the documented--header <name>:<value>form previously threw an unhandledTypeError, and now reports a clear error.Handle and explain authentication failures from remote bindings during local development
Wrangler now recognizes authentication failures from remote preview sessions and reports that bindings which need to run remotely require Cloudflare authentication even when the rest of the Worker is developed locally.
Speed up old debug log cleanup by reading each log file's date from its filename instead of
stat-ing every fileWrangler periodically deletes debug log files older than 30 days from its logs directory. Previously it made a filesystem
statcall for each file to read its modification time; it now derives the age from the timestamp already encoded in the log filename, avoiding that extra work.
4.114.0
23 Jul 2026Add local-dev observability
wrangler devand the Vite plugin now capture a trace for every local Worker invocation - spans, logs, andconsole.*output, including requests that cross worker or Durable Object boundaries.You can explore this data two ways:
While this is in testing it's off by default; set
X_LOCAL_OBSERVABILITY=trueto turn it on. It will be on by default in the public release.Improve the D1 database-limit error message
When creating a D1 database fails because the account has hit its database limit, the error now points to the relevant next steps — upgrading on the Workers Free plan or requesting a higher limit on a paid plan — alongside the existing commands to list and delete databases. Previously it only suggested deleting unused databases. This applies both to
wrangler d1 createand to the D1 database that is created during resource provisioning on deploy.Fix grammar in the container image-too-large error
The error thrown when a container image exceeds the available disk size ended with "Your need more disk for this image." It now reads "You need more disk for this image."
Minor Changes
Add local-dev observability
wrangler devand the Vite plugin now capture a trace for every local Worker invocation - spans, logs, andconsole.*output, including requests that cross worker or Durable Object boundaries.You can explore this data two ways:
A new Observability tab in the Local Explorer, with a Traces view (recent invocations, an inline timeline waterfall, and filters) and an Events view.
A read-only SQL endpoint at
/cdn-cgi/explorer/api/local/observability/query, discoverable via the Local Explorer's OpenAPI document, so coding agents and tools can query the samespansandlogstables.
While this is in testing it's off by default; set
X_LOCAL_OBSERVABILITY=trueto turn it on. It will be on by default in the public release.
Patch Changes
Improve the D1 database-limit error message
When creating a D1 database fails because the account has hit its database limit, the error now points to the relevant next steps — upgrading on the Workers Free plan or requesting a higher limit on a paid plan — alongside the existing commands to list and delete databases. Previously it only suggested deleting unused databases. This applies both to
wrangler d1 createand to the D1 database that is created during resource provisioning on deploy.Fix grammar in the container image-too-large error
The error thrown when a container image exceeds the available disk size ended with "Your need more disk for this image." It now reads "You need more disk for this image."
Ignore the removed
legacy_envfield when reading a redirected configurationOlder versions of tools such as the Vite plugin can generate a redirected configuration (
.wrangler/deploy/config.json) that still includes the removedlegacy_envfield. Since these files are tool-generated, users could not easily remove the field themselves, and Wrangler would error out. Wrangler now silently stripslegacy_envfrom redirected configurations. User-authored configurations still report an error so that the field can be removed.Fix dev proxy silently hanging or returning a misleading 503 on network errors for non-root-path requests
During
wrangler dev, a transient network error on any request path other than/could be misclassified as the worker being reloaded, even when it wasn't:GET/HEADrequests would silently hang (with nothing logged) until the client timed out, and other methods would receive a misleadingYour worker restarted mid-request503. Such errors are now reported and surfaced immediately when the worker has not actually changed.Explain how to provision Flagship bindings if
app_idmissing in remote developmentWrangler now reports that a Flagship binding without an
app_idmust first be created withwrangler flagship apps create.