Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions .changeset/retrieve-compiled-config-build-output-path.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
---
"@opennextjs/cloudflare": patch
---

Fix `deploy`/`preview`/`upload`/`populateCache` failing when `buildOutputPath` is set

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 Changeset description does not follow the repository's required message format

The new changeset body starts with a plain sentence instead of the mandated <type>: <imperative title> first line (.changeset/retrieve-compiled-config-build-output-path.md:5), so the generated changelog entry is inconsistent with every other entry.
Impact: The released changelog entry will not carry the required fix: prefix and imperative title format.

Rule reference

CONTRIBUTING.md ("Changeset message format") and AGENTS.md ("Changesets") both require the body to begin with <TYPE>: <TITLE> where TYPE is one of feature | fix | refactor | docs | chore. The current first line is "Fix deploy/preview/upload/populateCache failing when buildOutputPath is set".

Suggested change
Fix `deploy`/`preview`/`upload`/`populateCache` failing when `buildOutputPath` is set
fix: make `retrieveCompiledConfig` respect `buildOutputPath`
Open in Devin Review

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


`retrieveCompiledConfig` looked for the compiled config under a hardcoded
`<cwd>/.open-next/.build/`, which does not follow the `buildOutputPath` config.
Every command that goes through it therefore exited with `Could not find
compiled Open Next config, did you run the build command?` right after a
successful build. `build` itself was unaffected because it compiles the config
from source, so the failure only showed up at deploy time.

The compiled path cannot simply be prefixed with `buildOutputPath` — that value
lives in the very config being loaded. When the file is missing, the config is
now recompiled from source instead (the same path `build` takes;
`compileOpenNextConfig` emits to a temp dir, so nothing lands in the project).
7 changes: 5 additions & 2 deletions packages/cloudflare/src/cli/commands/utils/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,8 +98,11 @@ export async function retrieveCompiledConfig() {
const configPath = path.join(nextAppDir, ".open-next/.build/open-next.config.edge.mjs");

if (!existsSync(configPath)) {
logger.error("Could not find compiled Open Next config, did you run the build command?");
process.exit(1);
// The path above does not follow a custom `buildOutputPath`, which moves the compiled
// config out of `<cwd>/.open-next`. It cannot be resolved here either -- it lives in
// the very config we are trying to load. Recompile from the source config instead:
// `compileOpenNextConfig` emits to a temp dir, so nothing lands in the project.
return compileConfig(undefined);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 Deploying without building first no longer tells the user to run a build

When the built output is missing, the command now quietly rebuilds the configuration from source (compileConfig(undefined) at packages/cloudflare/src/cli/commands/utils/utils.ts:105) instead of stopping with the previous "did you run the build command?" message, so a user who forgot to build gets an unrelated later failure or is even asked to create a new project config file mid-deploy.
Impact: Users running deploy/preview/upload/populate-cache before building see confusing downstream errors, and in an interactive terminal the command can prompt for and write a new config file into the project.

Why the fallback swallows the missing-build case

retrieveCompiledConfig previously distinguished "no build output" from other errors and exited with an actionable message. The new fallback cannot distinguish "buildOutputPath moved the compiled config" from "no build was ever run", so both take the recompile path. compileConfig (packages/cloudflare/src/cli/commands/utils/utils.ts:58-90) additionally may call askConfirmation and createOpenNextConfigFile(nextAppDir, ...) which writes open-next.config.ts into the project — a write side effect that deploy/upload never had before. In CI the error becomes "No open-next.config.ts file was found ... run opennextjs-cloudflare migrate", which is misleading when the real problem is a missing build.

A better shape would be to keep the fallback only after confirming a source config exists, and still surface a build-missing warning/error when the produced worker output is absent.

Prompt for agents
In packages/cloudflare/src/cli/commands/utils/utils.ts, retrieveCompiledConfig now falls back to compileConfig(undefined) whenever <cwd>/.open-next/.build/open-next.config.edge.mjs is absent. This conflates two very different situations: (a) a custom buildOutputPath moved the compiled config, and (b) the user never ran the build. Case (b) previously produced a clear actionable error; now it either fails later with an obscure wrangler error, or (in an interactive shell) prompts the user and writes a new open-next.config.ts into their project via createOpenNextConfigFile. Consider only falling back when a source open-next config actually exists (findOpenNextConfig), never creating a config file from these commands, and still emitting the 'did you run the build command?' error when neither compiled nor source config is available.
Open in Devin Review

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

}

const config = await import(url.pathToFileURL(configPath).href).then((mod) => mod.default);
Expand Down