Skip to content

Commit dfba912

Browse files
Fix wrangler deploy erroring when it pulls down remote configs of workers containing an assets binding (#11339)
* Fix `wrangler deploy` erroring when it pulls down remote configs of workers containing an assets binding * Ensure that extra assets values are not being shown in the wrangler deploy remote diff
1 parent 52ebfa9 commit dfba912

File tree

7 files changed

+116
-18
lines changed

7 files changed

+116
-18
lines changed

.changeset/full-ends-sell.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
---
2+
"@cloudflare/workers-utils": patch
3+
---
4+
5+
Fix `mapWorkerMetadataBindings` and `constructWranglerConfig` incorrectly throwing an error when encountering assets bindings
6+
7+
Currently `mapWorkerMetadataBindings` and `constructWranglerConfig` when provided data containing an assets binding throw the
8+
following error:
9+
10+
```
11+
the error "`wrangler init --from-dash` is not yet supported for Workers with Assets"
12+
```
13+
14+
This is incorrect and `wrangler init` specific, the changes here make sure that such error is not thrown and that the assets
15+
binding is instead handled

.changeset/soft-friends-obey.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"wrangler": patch
3+
---
4+
5+
Fix `wrangler deploy` erroring when it pulls down remote configs of workers containing an assets binding

packages/workers-utils/src/map-worker-metadata-bindings.ts

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import { assertNever } from "./assert-never";
2-
import { FatalError } from "./errors";
32
import type { RawConfig } from "./config";
43
import type { WorkerMetadataBinding } from "./types";
54

@@ -282,9 +281,13 @@ export function mapWorkerMetadataBindings(
282281
];
283282
break;
284283
case "assets":
285-
throw new FatalError(
286-
"`wrangler init --from-dash` is not yet supported for Workers with Assets"
287-
);
284+
configObj.assets = {
285+
binding: binding.name,
286+
// Note: we currently don't get all the assets information from the
287+
// API, so here we are only able to set the name of the binding
288+
// hopefully in the future we can properly fully support the binding
289+
};
290+
break;
288291
case "inherit":
289292
configObj.unsafe = {
290293
bindings: [...(configObj.unsafe?.bindings ?? []), binding],

packages/wrangler/src/__tests__/deploy.test.ts

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15310,6 +15310,10 @@ export default{
1531015310
it("in non-intractive (and non-strict) mode, should present a diff when there are differences between the local config and the dash config, and proceed with the deployment", async () => {
1531115311
setIsTTY(false);
1531215312

15313+
fs.mkdirSync("./public");
15314+
15315+
await mockAUSRequest([]);
15316+
1531315317
writeWorkerSource();
1531415318
mockGetServiceByName("test-name", "production", "dash");
1531515319
writeWranglerConfig(
@@ -15321,6 +15325,12 @@ export default{
1532115325
vars: {
1532215326
MY_VAR: "this is a toml file",
1532315327
},
15328+
assets: {
15329+
binding: "ASSETS",
15330+
// Note: remotely we only get the assets' binding name, so in the diff below you can see that
15331+
// no diff for the directory configuration is shown
15332+
directory: "public",
15333+
},
1532415334
observability: {
1532515335
enabled: true,
1532615336
},
@@ -15357,20 +15367,23 @@ export default{
1535715367
// to be able to show toml content/diffs, that combined with the fact that json(c) config files are the
1535815368
// recommended ones moving forward makes this small shortcoming of the config diffing acceptable
1535915369
expect(normalizeLogWithConfigDiff(std.warn)).toMatchInlineSnapshot(`
15360-
"▲ [WARNING] The local configuration being used (generated from your local configuration file) differs from the remote configuration of your Worker set via the Cloudflare Dashboard:
15370+
"▲ [WARNING] The local configuration being used (generated from your local configuration file) differs from the remote configuration of your Worker set via the Cloudflare Dashboard:
1536115371
15362-
{
15363-
vars: {
15364-
- MY_VAR: \\"abc\\"
15365-
+ MY_VAR: \\"this is a toml file\\"
15366-
}
15367-
}
15372+
{
15373+
+ assets: {
15374+
+ binding: \\"ASSETS\\"
15375+
+ }
15376+
vars: {
15377+
- MY_VAR: \\"abc\\"
15378+
+ MY_VAR: \\"this is a toml file\\"
15379+
}
15380+
}
1536815381
1536915382
15370-
Deploying the Worker will override the remote configuration with your local one.
15383+
Deploying the Worker will override the remote configuration with your local one.
1537115384
15372-
"
15373-
`);
15385+
"
15386+
`);
1537415387

1537515388
expect(std.out).toMatchInlineSnapshot(`
1537615389
"
@@ -15382,6 +15395,7 @@ export default{
1538215395
Worker Startup Time: 100 ms
1538315396
Your Worker has access to the following bindings:
1538415397
Binding Resource
15398+
env.ASSETS Assets
1538515399
env.MY_VAR (\\"this is a toml file\\") Environment Variable
1538615400
1538715401
Uploaded test-name (TIMINGS)

packages/wrangler/src/__tests__/deploy/get-remote-config-diff.test.ts

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -480,6 +480,47 @@ describe("getRemoteConfigsDiff", () => {
480480
expect(diff).toBeNull();
481481
});
482482

483+
it("should ignore all fields from an assets binding besides the binding name (since remotely only that information is stored)", () => {
484+
const { diff, nonDestructive } = getRemoteConfigDiff(
485+
{
486+
name: "my-worker-id",
487+
main: "/tmp/src/index.js",
488+
workers_dev: true,
489+
preview_urls: false,
490+
compatibility_date: "2025-07-08",
491+
account_id: "account-id-123",
492+
assets: {
493+
binding: "ASSETS",
494+
},
495+
},
496+
{
497+
name: "my-worker-id",
498+
main: "/tmp/src/index.js",
499+
workers_dev: true,
500+
preview_urls: false,
501+
compatibility_date: "2025-07-08",
502+
account_id: "account-id-123",
503+
assets: {
504+
binding: "MY_ASSETS",
505+
// Note: The directory and html_handling fields are ignored
506+
directory: "public",
507+
html_handling: "drop-trailing-slash",
508+
},
509+
} as unknown as Config
510+
);
511+
assert(diff);
512+
expect(normalizeDiff(diff.toString())).toMatchInlineSnapshot(`
513+
" {
514+
assets: {
515+
- binding: \\"ASSETS\\"
516+
+ binding: \\"MY_ASSETS\\"
517+
}
518+
}
519+
"
520+
`);
521+
expect(nonDestructive).toBe(false);
522+
});
523+
483524
// The Observability field in the remote configuration has some specific behaviors, for that we have
484525
// the following tests to make double sure to get these various observability cases right
485526
// (note: this is however a best effort diffing since we cannot really perform a full one since we loose

packages/wrangler/src/deploy/config-diffs.ts

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,14 @@ function normalizeLocalResolvedConfigAsRemote(
7676

7777
removeRemoteConfigFieldFromBindings(normalizedConfig);
7878

79+
// Currently remotely we only get the assets' binding name, so we need remove
80+
// everything else, if present, from the local one
81+
if (normalizedConfig.assets) {
82+
normalizedConfig.assets = {
83+
binding: normalizedConfig.assets.binding,
84+
};
85+
}
86+
7987
return normalizedConfig;
8088
}
8189

@@ -250,9 +258,15 @@ function normalizeRemoteConfigAsResolvedLocal(
250258
// in this way we can make sure that local-only configurations are not shown as
251259
// differences between local and remote configs
252260
Object.entries(localResolvedConfig).forEach(([key, value]) => {
253-
// We want to skip observability since it has a remote default behavior
254-
// different from that of wrangler
255-
if (key !== "observability") {
261+
if (
262+
// We want to skip observability since it has a remote default behavior
263+
// different from that of wrangler
264+
key !== "observability" &&
265+
// We want to skip assets since it is a special case, the issue being that
266+
// remotely assets configs only include at most the binding name and we
267+
// already address that in the local config normalization already
268+
key !== "assets"
269+
) {
256270
(normalizedRemote as unknown as Record<string, unknown>)[key] = value;
257271
}
258272
});

packages/wrangler/src/init.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { mkdir, writeFile } from "node:fs/promises";
22
import path, { dirname } from "node:path";
3-
import { UserError } from "@cloudflare/workers-utils";
3+
import { FatalError, UserError } from "@cloudflare/workers-utils";
44
import { execa } from "execa";
55
import { fetchResult } from "./cfetch";
66
import { fetchWorkerDefinitionFromDash } from "./cfetch/internal";
@@ -164,6 +164,12 @@ export async function downloadWorker(accountId: string, workerName: string) {
164164
accountId
165165
);
166166

167+
if (config.assets) {
168+
throw new FatalError(
169+
"`wrangler init --from-dash` is not yet supported for Workers with Assets"
170+
);
171+
}
172+
167173
return {
168174
modules,
169175
config,

0 commit comments

Comments
 (0)