Skip to content

Allow users to run local dev or tests on static asset workers when the assets dir doesn't exist#13116

Draft
dario-piotrowicz wants to merge 1 commit intomainfrom
dario/allow-dev-and-tests-when-no-assets-dir-exist
Draft

Allow users to run local dev or tests on static asset workers when the assets dir doesn't exist#13116
dario-piotrowicz wants to merge 1 commit intomainfrom
dario/allow-dev-and-tests-when-no-assets-dir-exist

Conversation

@dario-piotrowicz
Copy link
Copy Markdown
Member

@dario-piotrowicz dario-piotrowicz commented Mar 29, 2026

Users running local dev (wrangler dev, vite dev) or tests (using vitest-pool-workers) might want to specify an assets directory that not yet exists (because it gets built as part of the build process for example). The changes in this PR allow all the above mentioned to work even if the assets directory doesn't exist yet.

wrangler deploy (and similar commands) still fails if the directory doesn't exist at deploy time


  • Tests
    • Tests included/updated
    • Automated tests not possible - manual testing has been completed as follows:
    • Additional testing not necessary because:
  • Public documentation
    • Cloudflare docs PR(s):
    • Documentation not necessary because: self-documenting improvement

A picture of a cute animal (not mandatory, but encouraged)


Open with Devin

@changeset-bot
Copy link
Copy Markdown

changeset-bot bot commented Mar 29, 2026

🦋 Changeset detected

Latest commit: e7874c0

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

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

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

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Mar 29, 2026

✅ All changesets look good

Copy link
Copy Markdown
Contributor

@ask-bonk ask-bonk bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm Bonk, and I've done a quick review of your PR.

This PR relaxes the assets-directory-existence check for local dev / test paths while keeping it enforced for deploy. Good change overall, but I spotted a functional regression and some dead code left behind.

Issues (highest severity first)

  1. Bug: overrides parameter dropped in unstable_getMiniflareWorkerOptions — The old call was getAssetsOptions({ assets: undefined }, config, options?.overrides?.assets). The refactored call no longer passes overrides, so any caller providing asset overrides will have them silently ignored. See inline suggestion.

  2. Dead code: NonExistentAssetsDirError catch is now unreachable in getMiniflareOptionsFromConfig — Since validateDirectoryExistence is now false, getAssetsOptions will never throw NonExistentAssetsDirError. The try/catch block (lines 273-290) and the NonExistentAssetsDirError import are now dead code and should be cleaned up — just call getAssetsOptions(...) directly without the try/catch.

  3. Minor: temp directory accumulation in Miniflare — Each getServices() call when the directory doesn't exist creates a new mkdtemp directory that is never cleaned up. During a long dev session with repeated setOptions() calls (e.g. file-watcher triggers while the build output still doesn't exist), empty temp directories will accumulate in /tmp. Not a big deal since the OS cleans /tmp eventually, but worth noting.

Comment thread packages/wrangler/src/api/integrations/platform/index.ts
Comment on lines +274 to +281
processedAssetOptions = getAssetsOptions({
args: {
assets: undefined,
},
config,
// For getPlatformProxy/local dev we don't need to validate the directory's existence
validateDirectoryExistence: false,
});
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Dead code: since validateDirectoryExistence is now false, getAssetsOptions will never throw NonExistentAssetsDirError, making the surrounding try/catch block (through line 290) unreachable. Consider removing the try/catch and calling getAssetsOptions(...) directly.

@ask-bonk

This comment was marked as outdated.

@dario-piotrowicz dario-piotrowicz force-pushed the dario/allow-dev-and-tests-when-no-assets-dir-exist branch from 35a7ee2 to 83fc91d Compare March 29, 2026 22:47
@pkg-pr-new
Copy link
Copy Markdown

pkg-pr-new bot commented Mar 29, 2026

create-cloudflare

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

@cloudflare/kv-asset-handler

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

miniflare

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

@cloudflare/pages-shared

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

@cloudflare/unenv-preset

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

@cloudflare/vite-plugin

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

@cloudflare/vitest-pool-workers

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

@cloudflare/workers-editor-shared

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

wrangler

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

commit: e7874c0

@dario-piotrowicz dario-piotrowicz force-pushed the dario/allow-dev-and-tests-when-no-assets-dir-exist branch from 83fc91d to 5e3a05c Compare March 29, 2026 22:54
@penalosa
Copy link
Copy Markdown
Contributor

How does this compare to #13079?

Base automatically changed from dario/better-error-message-ENOTDIR-assets-dir to main March 30, 2026 13:21
@dario-piotrowicz dario-piotrowicz force-pushed the dario/allow-dev-and-tests-when-no-assets-dir-exist branch from 5e3a05c to e7874c0 Compare March 30, 2026 13:44
@dario-piotrowicz
Copy link
Copy Markdown
Member Author

How does this compare to #13079?

isn't #13079 addressing the case when a directory is not specified in the config file?

this PR instead is handling the case when a directory is specified but doesn't actually (yet) exist on the filesystem

no?

@dario-piotrowicz dario-piotrowicz marked this pull request as ready for review March 30, 2026 13:48
@dario-piotrowicz dario-piotrowicz requested a review from a team as a code owner March 30, 2026 13:48
@workers-devprod
Copy link
Copy Markdown
Contributor

Codeowners approval required for this PR:

  • @cloudflare/wrangler
Show detailed file reviewers
  • packages/miniflare/src/plugins/assets/index.ts: [@cloudflare/wrangler]
  • packages/miniflare/test/plugins/assets/index.spec.ts: [@cloudflare/wrangler]
  • packages/wrangler/src/tests/assets.test.ts: [@cloudflare/wrangler]
  • packages/wrangler/src/tests/dev.test.ts: [@cloudflare/wrangler]
  • packages/wrangler/src/api/integrations/platform/index.ts: [@cloudflare/wrangler]
  • packages/wrangler/src/api/startDevWorker/ConfigController.ts: [@cloudflare/wrangler]
  • packages/wrangler/src/assets.ts: [@cloudflare/wrangler]
  • packages/wrangler/src/deploy/index.ts: [@cloudflare/wrangler]
  • packages/wrangler/src/dev.ts: [@cloudflare/wrangler]
  • packages/wrangler/src/triggers/index.ts: [@cloudflare/wrangler]
  • packages/wrangler/src/versions/upload.ts: [@cloudflare/wrangler]

Copy link
Copy Markdown
Contributor

@devin-ai-integration devin-ai-integration bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Devin Review found 1 potential issue.

View 4 additional findings in Devin Review.

Open in Devin Review

Comment on lines +501 to +507
${
(formatConfigSnippet(
{ compatibility_date: compatibilityDateStr },
config.configPath
),
false)
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔴 Comma operator causes error message to display "false" instead of config snippet

The expression (formatConfigSnippet({ compatibility_date: compatibilityDateStr }, config.configPath), false) uses JavaScript's comma operator: it evaluates the formatConfigSnippet() call, discards the returned string, and the whole expression evaluates to false. The error message shown when compatibility_date is missing during wrangler versions upload will contain the literal text false instead of the actual config snippet.

Comparison with correct usage in deploy.ts

The correct pattern is used in packages/wrangler/src/deploy/deploy.ts:557:

${formatConfigSnippet({ compatibility_date: compatibilityDateStr }, config.configPath, false)}

Here false is passed as the third argument (the formatted parameter) to formatConfigSnippet, which controls JSON formatting. But in versions/upload.ts, false is instead the second operand of the comma operator.

Suggested change
${
(formatConfigSnippet(
{ compatibility_date: compatibilityDateStr },
config.configPath
),
false)
}
${formatConfigSnippet(
{ compatibility_date: compatibilityDateStr },
config.configPath,
false
)}
Open in Devin Review

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

@penalosa
Copy link
Copy Markdown
Contributor

@dario-piotrowicz do you have a link to an issue or something where this was discussed? I'm not 100% sure this is a good idea, and I think I would generally expect a missing assets dir to trigger a hard error. Vite deals with this by making the assets dir config field optional, which feels right to me.

@dario-piotrowicz
Copy link
Copy Markdown
Member Author

@dario-piotrowicz do you have a link to an issue or something where this was discussed? I'm not 100% sure this is a good idea, and I think I would generally expect a missing assets dir to trigger a hard error. Vite deals with this by making the assets dir config field optional, which feels right to me.

I thought there was a general consensus that we shouldn't hard error... 🤔

See: https://github.com/cloudflare/workers-sdk/blame/9282493b11ba07bcadb981c2cfc255e8eb5b9b15/packages/wrangler/src/api/integrations/platform/index.ts#L277-L279

@penalosa
Copy link
Copy Markdown
Contributor

@dario-piotrowicz maybe I'm talking nonsense, and definitely feel free to disagree with me! But in general my thinking is:

  • not erroring in getPlatformProxy() makes sense, because that's used at dev time in dev servers that probably haven't built assets yet
  • not erroring when assets directory isn't specified makes sense, because that's either Vite, or a mistake that will give a clear error at dev/deploy-time
  • not erroring when assets directory doesn't exist but is specified seems more dangerous, because there are lots of ways that could happen. In particular, I'd be worried about typos etc... and then a really frustrating debugging experience trying to figure out why assets aren't available

@dario-piotrowicz
Copy link
Copy Markdown
Member Author

@dario-piotrowicz maybe I'm talking nonsense, and definitely feel free to disagree with me! But in general my thinking is:

  • not erroring in getPlatformProxy() makes sense, because that's used at dev time in dev servers that probably haven't built assets yet
  • not erroring when assets directory isn't specified makes sense, because that's either Vite, or a mistake that will give a clear error at dev/deploy-time
  • not erroring when assets directory doesn't exist but is specified seems more dangerous, because there are lots of ways that could happen. In particular, I'd be worried about typos etc... and then a really frustrating debugging experience trying to figure out why assets aren't available

Sounds good 👍 , I'll update the PR accordingly

The only point that I don't fully agree is the last one, if users run something like wrangler dev and the assets dir doesn't exist, I don't see much danger in that since we're talking about local dev anyways, but I understand your point that this could surprise users/create a bit of a frustrating debugging experience 👍

@dario-piotrowicz dario-piotrowicz marked this pull request as draft March 30, 2026 15:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Untriaged

Development

Successfully merging this pull request may close these issues.

3 participants