Skip to content

Releases: cloudflare/workers-sdk

miniflare@4.20260701.0

Choose a tag to compare

@workers-devprod workers-devprod released this 02 Jul 16:33
473e61f

Patch Changes

  • #14502 6b0ce98 Thanks @dependabot! - Update dependencies of "miniflare", "wrangler"

    The following dependency versions have been updated:

    Dependency From To
    workerd 1.20260630.1 1.20260701.1

@cloudflare/workers-utils@0.25.0

Choose a tag to compare

@workers-devprod workers-devprod released this 02 Jul 16:33
473e61f

Minor Changes

  • #14474 aa5d580 Thanks @WillTaylorDev! - Add cache options for WorkerEntrypoint exports

    You can now set cache options on WorkerEntrypoint exports and configure cross-version cache behavior globally:

    // wrangler.json
    {
      "cache": { "enabled": true, "cross_version_cache": true },
      "exports": {
        "default": {
          "type": "worker",
          "cache": { "enabled": false }
        },
        "Admin": {
          "type": "worker",
          "cache": { "enabled": true }
        }
      }
    }

    Wrangler sends the exports config to the deploy and version upload APIs alongside the global cache.enabled and cache.cross_version_cache settings. The platform resolves those global settings plus cache overrides on exports and validates which entrypoint names are cacheable.

@cloudflare/workers-auth@0.4.0

Choose a tag to compare

@workers-devprod workers-devprod released this 02 Jul 16:33
473e61f

Minor Changes

  • #14156 e1532eb Thanks @petebacondarwin! - Add opt-in OS keychain storage for OAuth credentials

    By default wrangler stores your OAuth tokens in a plaintext file, and that is unchanged. You can now opt in to encrypting them at rest instead: wrangler login --use-keyring writes the tokens to an AES-256-GCM-encrypted file whose key is held in your OS keyring (macOS Keychain, libsecret on Linux, or Windows Credential Manager). Existing plaintext credentials are migrated automatically on first use.

    Toggle it with any of:

    • wrangler login --use-keyring / --no-use-keyring
    • wrangler auth keyring enable / disable (or wrangler auth keyring to print the current setting) — useful if you only use named profiles and never run the global wrangler login
    • CLOUDFLARE_AUTH_USE_KEYRING=true|false to override the saved preference for a single command

    Opting out deletes the encrypted credentials rather than decrypting them back to disk, so you re-authenticate afterwards. The preference applies to every auth profile, and each named profile gets its own encrypted file and key.

    Per-platform requirements: macOS uses the built-in security tool (nothing to install); Linux uses secret-tool from libsecret-tools (wrangler prints an install hint if it is missing); Windows lazily installs @napi-rs/keyring (~1.9 MB) on first opt-in, and errors with instructions in non-interactive/CI contexts.

    CLOUDFLARE_API_TOKEN and CLOUDFLARE_API_KEY/CLOUDFLARE_EMAIL continue to take priority over any stored OAuth credentials.

Patch Changes

  • Updated dependencies [aa5d580]:
    • @cloudflare/workers-utils@0.25.0

@cloudflare/vitest-pool-workers@0.18.0

Choose a tag to compare

@workers-devprod workers-devprod released this 02 Jul 16:33
473e61f

Minor Changes

  • #14382 fd92d56 Thanks @petebacondarwin! - Add support for declarative Durable Object exports

    wrangler deploy now accepts an exports map in wrangler.json as a declarative alternative to the legacy migrations array.

    Each entry in exports is keyed by Durable Object class name. type carries the export kind (currently always "durable-object"); the state field carries the lifecycle and defaults to "created" (live) when omitted:

    {
      "exports": {
        // Provision a new Durable Object class (`MyDO`)
        "MyDO": { "type": "durable-object", "storage": "sqlite" },
        // Delete Durable Object class (`OldGone`)
        "OldGone": { "type": "durable-object", "state": "deleted" },
        // Rename a Durable Object class (from `OldName` to `NewName`)
        "OldName": {
          "type": "durable-object",
          "state": "renamed",
          "renamed_to": "NewName"
        },
        "NewName": { "type": "durable-object", "storage": "sqlite" },
        // Transfer a Durable Object (`Outgoing`) to a new Worker (`target-worker`)
        "Outgoing": {
          "type": "durable-object",
          "state": "transferred",
          "transferred_to": "target-worker"
        },
        // Prepare to receive the transfer of a Durable Object (`Incoming`) from another Worker (`source-worker`)
        "Incoming": {
          "type": "durable-object",
          "state": "expecting-transfer",
          "storage": "sqlite",
          "transfer_from": "source-worker"
        }
      }
    }

    When a Worker declares Durable Object class bindings but no lifecycle for them (neither a migrations array nor an exports map), wrangler warns and now suggests a declarative exports entry for each class (previously it suggested a legacy migrations block).

    The deployment response now surfaces the server's reconciliation result — created namespaces, applied tombstones, structured per-scenario info entries, and a removable_entries hint for stale tombstones that are safe to delete from the config. Blocking errors return the structured per-class detail with scenario tags, suggested remediation, and any referencing-script context.

    wrangler versions upload also forwards exports. Declarative exports lifecycle changes are reconciled when the version is deployed (wrangler versions deploy or wrangler deploy), so a versions upload payload can declare new classes in exports without immediately provisioning them. An actor binding (durable_objects.bindings) to a class declared only in exports on the same versions upload is rejected with a clear error (code 100406) — the binding cannot be resolved until the namespace is provisioned. Either stage the new class via ctx.exports.X (no binding required) on versions upload and add the binding at deploy time, or use wrangler deploy to provision and bind in one step (the same constraint applies to the migrations flow).

    Multi-version deploys (wrangler versions deploy A@50% B@50%) where the selected versions disagree on declarative exports are rejected server-side with a clear message: deploy the version that changes exports at 100% first, then run the percentage-split deploy. This prevents traffic on one branch routing to code that references unprovisioned or just-deleted DO namespaces. Single-version (100%) deploys are unaffected.

    Local development (wrangler dev, vite dev and unstable_startWorker) reads Durable Object SQLite storage settings from the new exports field, so applications using the declarative flow get correct local-dev storage without needing to also declare a migrations block.

    @cloudflare/vitest-pool-workers also picks up Durable Object configuration from exports, so tests against an exports-only Worker run with the correct local SQLite storage and can reach unbound Durable Object classes via ctx.exports.X.

    wrangler types is also aware of exports. Live entries (including expecting-transfer, the receiving side of a two-phase transfer) are added to Cloudflare.GlobalProps.durableNamespaces, which types ctx.exports.X for unbound Durable Objects declared only via exports.

Patch Changes

@cloudflare/vite-plugin@1.43.0

Choose a tag to compare

@workers-devprod workers-devprod released this 02 Jul 16:33
473e61f

Minor Changes

  • #14382 fd92d56 Thanks @petebacondarwin! - Add support for declarative Durable Object exports

    wrangler deploy now accepts an exports map in wrangler.json as a declarative alternative to the legacy migrations array.

    Each entry in exports is keyed by Durable Object class name. type carries the export kind (currently always "durable-object"); the state field carries the lifecycle and defaults to "created" (live) when omitted:

    {
      "exports": {
        // Provision a new Durable Object class (`MyDO`)
        "MyDO": { "type": "durable-object", "storage": "sqlite" },
        // Delete Durable Object class (`OldGone`)
        "OldGone": { "type": "durable-object", "state": "deleted" },
        // Rename a Durable Object class (from `OldName` to `NewName`)
        "OldName": {
          "type": "durable-object",
          "state": "renamed",
          "renamed_to": "NewName"
        },
        "NewName": { "type": "durable-object", "storage": "sqlite" },
        // Transfer a Durable Object (`Outgoing`) to a new Worker (`target-worker`)
        "Outgoing": {
          "type": "durable-object",
          "state": "transferred",
          "transferred_to": "target-worker"
        },
        // Prepare to receive the transfer of a Durable Object (`Incoming`) from another Worker (`source-worker`)
        "Incoming": {
          "type": "durable-object",
          "state": "expecting-transfer",
          "storage": "sqlite",
          "transfer_from": "source-worker"
        }
      }
    }

    When a Worker declares Durable Object class bindings but no lifecycle for them (neither a migrations array nor an exports map), wrangler warns and now suggests a declarative exports entry for each class (previously it suggested a legacy migrations block).

    The deployment response now surfaces the server's reconciliation result — created namespaces, applied tombstones, structured per-scenario info entries, and a removable_entries hint for stale tombstones that are safe to delete from the config. Blocking errors return the structured per-class detail with scenario tags, suggested remediation, and any referencing-script context.

    wrangler versions upload also forwards exports. Declarative exports lifecycle changes are reconciled when the version is deployed (wrangler versions deploy or wrangler deploy), so a versions upload payload can declare new classes in exports without immediately provisioning them. An actor binding (durable_objects.bindings) to a class declared only in exports on the same versions upload is rejected with a clear error (code 100406) — the binding cannot be resolved until the namespace is provisioned. Either stage the new class via ctx.exports.X (no binding required) on versions upload and add the binding at deploy time, or use wrangler deploy to provision and bind in one step (the same constraint applies to the migrations flow).

    Multi-version deploys (wrangler versions deploy A@50% B@50%) where the selected versions disagree on declarative exports are rejected server-side with a clear message: deploy the version that changes exports at 100% first, then run the percentage-split deploy. This prevents traffic on one branch routing to code that references unprovisioned or just-deleted DO namespaces. Single-version (100%) deploys are unaffected.

    Local development (wrangler dev, vite dev and unstable_startWorker) reads Durable Object SQLite storage settings from the new exports field, so applications using the declarative flow get correct local-dev storage without needing to also declare a migrations block.

    @cloudflare/vitest-pool-workers also picks up Durable Object configuration from exports, so tests against an exports-only Worker run with the correct local SQLite storage and can reach unbound Durable Object classes via ctx.exports.X.

    wrangler types is also aware of exports. Live entries (including expecting-transfer, the receiving side of a two-phase transfer) are added to Cloudflare.GlobalProps.durableNamespaces, which types ctx.exports.X for unbound Durable Objects declared only via exports.

Patch Changes

@cloudflare/pages-shared@0.13.152

Choose a tag to compare

@workers-devprod workers-devprod released this 02 Jul 16:33
473e61f

Patch Changes

  • Updated dependencies [6b0ce98]:
    • miniflare@4.20260701.0

@cloudflare/deploy-helpers@0.3.0

Choose a tag to compare

@workers-devprod workers-devprod released this 02 Jul 16:33
473e61f

Minor Changes

  • #14474 aa5d580 Thanks @WillTaylorDev! - Add cache options for WorkerEntrypoint exports

    You can now set cache options on WorkerEntrypoint exports and configure cross-version cache behavior globally:

    // wrangler.json
    {
      "cache": { "enabled": true, "cross_version_cache": true },
      "exports": {
        "default": {
          "type": "worker",
          "cache": { "enabled": false }
        },
        "Admin": {
          "type": "worker",
          "cache": { "enabled": true }
        }
      }
    }

    Wrangler sends the exports config to the deploy and version upload APIs alongside the global cache.enabled and cache.cross_version_cache settings. The platform resolves those global settings plus cache overrides on exports and validates which entrypoint names are cacheable.

Patch Changes

  • #14305 98793d8 Thanks @jbwcloudflare! - Improve asset upload performance with single-file uploads

    Asset uploads now use a more efficient per-file upload path when the platform enables it. This is rolled out server-side and requires no configuration changes. Existing upload behavior is unchanged when the new path is not enabled.

  • Updated dependencies [aa5d580, 6b0ce98]:

    • @cloudflare/workers-utils@0.25.0
    • miniflare@4.20260701.0
    • @cloudflare/cli-shared-helpers@0.1.11

@cloudflare/cli-shared-helpers@0.1.11

Choose a tag to compare

@workers-devprod workers-devprod released this 02 Jul 16:33
473e61f

Patch Changes

  • Updated dependencies [aa5d580]:
    • @cloudflare/workers-utils@0.25.0

@cloudflare/autoconfig@0.1.2

Choose a tag to compare

@workers-devprod workers-devprod released this 02 Jul 16:33
473e61f

Patch Changes

  • Updated dependencies [aa5d580]:
    • @cloudflare/workers-utils@0.25.0
    • @cloudflare/cli-shared-helpers@0.1.11

wrangler@4.106.0

Choose a tag to compare

@workers-devprod workers-devprod released this 30 Jun 16:38
13c69dd

Minor Changes

  • #14490 75d8cb0 Thanks @petebacondarwin! - Add wrangler ai-search jobs commands for managing AI Search indexing jobs

    You can now list, trigger, inspect, cancel, and read the logs of indexing jobs for an AI Search instance:

    wrangler ai-search jobs list <instance>
    wrangler ai-search jobs create <instance> --description "manual reindex"
    wrangler ai-search jobs get <instance> <job-id>
    wrangler ai-search jobs cancel <instance> <job-id>
    wrangler ai-search jobs logs <instance> <job-id>
    

    All commands accept --namespace/-n (defaults to default). All commands except cancel also accept --json for clean machine-readable output.

  • #14490 75d8cb0 Thanks @petebacondarwin! - Add --source-jurisdiction to wrangler ai-search create for R2-backed instances

    R2 buckets can live in a specific jurisdiction (for example eu or fedramp). You can now point an AI Search instance at a bucket in one of those jurisdictions:

    wrangler ai-search create my-instance --type r2 --source my-bucket --source-jurisdiction eu

    When run interactively, the R2 source flow also prompts for a jurisdiction and lists (and can create) buckets within it. The value is a free-form string forwarded to the API as source_params.r2_jurisdiction (server-side validated); omit the flag for no specific jurisdiction. This AI Search command is in open beta.

  • #14490 75d8cb0 Thanks @petebacondarwin! - Add auth profiles for managing multiple OAuth logins

    Auth profiles let you maintain separate OAuth logins and bind them to directories, so you can switch between different accounts for different projects without having to re-login.

    For example:

    wrangler auth create work
    wrangler auth activate work ~/projects/work
    
    wrangler auth create personal
    wrangler auth activate personal ~/projects/personal

    New commands under wrangler auth:

    • wrangler auth create <name> — create or re-authenticate a named profile via OAuth
    • wrangler auth delete <name> — delete a profile and all its directory bindings
    • wrangler auth activate <name> [dir] — bind a profile to a directory (defaults to cwd). Sub-directories will inherit this profile.
    • wrangler auth deactivate [dir] — remove a directory binding
    • wrangler auth list — list all profiles and their corresponding directories

    There is also a new global --profile flag, which you can use to activate a profile for just that command run. Note that if you have CLOUDFLARE_API_TOKEN set, that will still take precedence over all profiles. Any account id settings (via CLOUDFLARE_ACCOUNT_ID or wrangler config) will also still be respected.

  • #14490 75d8cb0 Thanks @petebacondarwin! - Add --strict flag to wrangler versions upload and improve pre-upload safety checks

    wrangler versions upload now runs the same pre-upload checks as wrangler deploy:

    • When the Worker was last edited via the Cloudflare Dashboard, the local and remote configurations are diffed and you are warned only if the diff is destructive (previously, an unconditional warning was shown).
    • When local configuration values conflict with remote secrets, a warning is shown before proceeding.
    • When deploying workflows that belong to a different Worker, a warning is shown before proceeding.

    The new --strict flag (already available on wrangler deploy) causes wrangler versions upload to abort in non-interactive/CI environments when any of these conflicts are detected, instead of auto-continuing.

  • #14490 75d8cb0 Thanks @petebacondarwin! - Add D1 migration setup to createTestHarness() Worker handles

    Tests using createTestHarness() can now apply local D1 migrations before running requests:

    const worker = server.getWorker();
    
    beforeEach(async () => {
      await worker.applyD1Migrations("DATABASE");
    });
  • #14490 75d8cb0 Thanks @petebacondarwin! - Add Workflow introspection to createTestHarness()

    Worker handles can now introspect Workflow bindings by name, allowing tests to disable sleeps, mock step results, and wait for Workflow outcomes. Tests can introspect a known Workflow instance by ID or track instances created after introspection starts.

    const harness = createTestHarness({
    	workers: [{ configPath: "./wrangler.json" }],
    });
    
    const worker = harness.getWorker();
    await using workflow = await worker.introspectWorkflow("MY_WORKFLOW");
    
    await workflow.modifyAll((modifier) =>
    	modifier.disableSleeps([{ name: "wait-for-approval" }])
    );
    
    const response = await worker.fetch("/start-workflow");
    const [instance] = await workflow.get();
    await instance.waitForStatus("complete");
  • #14446 e0cc2cb Thanks @edmundhung! - Add bindingOverrides and getExport() to createTestHarness()

    Test harness workers loaded from Wrangler config files can now replace a configured binding with a Worker in the same harness. This is useful for replacing platform bindings with test Workers while keeping the source Worker config production-like. You can also call getExport() on a Worker returned by server.getWorker(name) to access JSRPC methods on the default Worker export, including mock Workers used as override targets.

    const server = createTestHarness({
      workers: [
        {
          configPath: "./workers/app/wrangler.jsonc",
          bindingOverrides: { BROWSER: "mock-browser" },
        },
        {
          // A mock Worker implementing the Browser Rendering binding named "mock-browser".
          configPath: "./workers/mock-browser/wrangler.jsonc",
        },
      ],
    });
    
    const mockBrowser = await server
      .getWorker<WebEnv, typeof import("./workers/mock-browser")>("mock-browser")
      .getExport();
    await mockBrowser.setScreenshot(stubPng);
    
    const response = await server.fetch("/reports/2026-05-29.png");
    expect(await response.bytes()).toEqual(stubPng);
  • #14490 75d8cb0 Thanks @petebacondarwin! - Improve wrangler tail resilience and shutdown behaviour

    wrangler tail previously crashed with a raw stack trace when the keep-alive ping to the Worker timed out, and could exit with an ugly error on Ctrl-C.

    • Errors now flow through wrangler's usual error pipeline instead of escaping as uncaught exceptions.
    • The keep-alive timeout message now clearly explains what happened and no longer prints a stack trace.
    • When the tail connection drops unexpectedly, wrangler tail now automatically tries to reconnect with exponential back-off (up to 5 retries).
    • Ctrl-C now prints a short "Stopping tail..." message (in pretty mode), awaits the server-side tail deletion, and exits cleanly with code 0.

Patch Changes

  • #14490 75d8cb0 Thanks @petebacondarwin! - Update dependencies of "miniflare", "wrangler"

    The following dependency versions have been updated:

    Dependency From To
    workerd 1.20260625.1 1.20260629.1
  • #14478 f10d4ad Thanks @dependabot! - Update dependencies of "miniflare", "wrangler"

    The following dependency versions have been updated:

    Dependency From To
    workerd 1.20260629.1 1.20260630.1
  • #14490 75d8cb0 Thanks @petebacondarwin! - Improve the deploy warning shown when a Workflow name already belongs to another Worker

    The warning still notes that deploying reassigns the workflow to the current Worker, and now also explains why this happens (workflow names must be unique per account) and how to resolve it (rename the workflow in the Wrangler config).

  • #14490 75d8cb0 Thanks @petebacondarwin! - use stream instead of deprecated pipeline key ...

Read more