Skip to content

Fix build failure when frontend_path is set without prerendering - #7044

Open
masenf wants to merge 3 commits into
mainfrom
claude/happy-brown-ajf67r
Open

Fix build failure when frontend_path is set without prerendering#7044
masenf wants to merge 3 commits into
mainfrom
claude/happy-brown-ajf67r

Conversation

@masenf

@masenf masenf commented Sep 4, 2026

Copy link
Copy Markdown
Collaborator

Type of change

  • Bug fix (non-breaking change which fixes an issue)

Description

Fixes a FileNotFoundError that occurs when running reflex run --env prod or reflex export with frontend_path configured and route prerendering disabled (REFLEX_SSR=false).

Root cause: When prerendering is disabled, the static output directory structure is not created with the frontend_path prefix. The build process attempted to move files into a non-existent prefix directory, causing the failure.

Solution: Explicitly create the prefix directory before attempting to relocate static files into it. This ensures the directory exists regardless of whether prerendering created it.

Changes

  1. reflex/utils/build.py: Modified the build() function to create the prefix directory before moving files, and simplified the file movement logic to use the pre-computed prefix_dir variable.

  2. tests/units/utils/test_build.py:

    • Extracted common test setup into _patch_build() helper to reduce duplication
    • Extracted static file creation into _write_static_output() helper
    • Added test_build_relocates_static_output_without_prerendered_prefix_dir() to verify files are correctly relocated when prerendering is off
    • Added test_build_merges_static_output_into_prerendered_prefix_dir() to verify prerendered output is preserved when merging with non-prerendered assets
  3. news/+frontend-path-noprerender-build.bugfix.md: Added changelog entry documenting the fix.

Test Plan

Added comprehensive unit tests covering both scenarios:

  • Static output relocation when the prefix directory doesn't exist (prerendering off)
  • Merging of static output into an existing prerendered prefix directory

All existing tests continue to pass.

https://claude.ai/code/session_01UwbNDEaQNGWeHWS8nxsURd

Review in cubic

… output

When frontend_path is set, build() moves every child of .web/build/client
into .web/build/client/<frontend_path>/. With route prerendering enabled,
React Router already emits the prerendered HTML under that prefix, so the
target directory exists by accident. With prerendering disabled
(REFLEX_SSR=false) nothing creates it: os.rename fails, shutil.move falls
back to copy2, and opening the destination raises FileNotFoundError,
crashing `reflex run --env prod` and `reflex export`.

Create the prefix directory up front so the relocation no longer depends
on prerendering. The existing skip for the prefix's first segment keeps
the prerendered output merging in as before.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UwbNDEaQNGWeHWS8nxsURd
@masenf
masenf requested a review from a team as a code owner September 4, 2026 18:58
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UwbNDEaQNGWeHWS8nxsURd
@codspeed-hq

codspeed-hq Bot commented Sep 4, 2026

Copy link
Copy Markdown

Merging this PR will not alter performance

✅ 32 untouched benchmarks
⏩ 8 skipped benchmarks1


Comparing claude/happy-brown-ajf67r (04b3cef) with main (fb04aa1)

Open in CodSpeed

Footnotes

  1. 8 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports.

@greptile-apps

greptile-apps Bot commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR creates the configured frontend prefix before relocating production build artifacts and adds regression coverage for builds with and without prerendered prefix output. The latest changes also reject parent-directory segments in frontend_path and document that configuration behavior.

  • Creates the relocation destination before moving static output.
  • Preserves existing prerendered files while merging other build assets.
  • Rejects bare .. path segments during configuration normalization.
  • Adds root-package and reflex-base changelog fragments.

Confidence Score: 4/5

The PR does not yet appear safe to merge because the existing output-containment issue remains unresolved.

The previous finding is only partially fixed: rejecting .. segments prevents the reported traversal form, but _normalize_paths ensures configured frontend paths begin with /, and converting that value to an absolute PosixPath means static_dir / frontend_path discards static_dir. Consequently, ordinary values such as /app can still create and populate an output directory outside .web/build/client.

Files Needing Attention: reflex/utils/build.py, packages/reflex-base/src/reflex_base/config.py

Important Files Changed

Filename Overview
reflex/utils/build.py Creates the frontend prefix directory before relocation, but the earlier path-containment finding remains only partially addressed.
packages/reflex-base/src/reflex_base/config.py Rejects parent-directory segments during normal configuration construction, while leaving absolute-path containment to the build logic.
tests/units/utils/test_build.py Adds coverage for absent and prerendered prefix directories, though the expected destination conflicts with absolute PosixPath joining semantics.
tests/units/test_config.py Covers rejection of bare parent segments and acceptance of non-traversal dotted names.

Reviews (2): Last reviewed commit: "Reject ".." segments in frontend_path" | Re-trigger Greptile

Comment thread reflex/utils/build.py

@cubic-dev-ai cubic-dev-ai Bot left a comment

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.

All reported issues were addressed across 3 files

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread reflex/utils/build.py
frontend_path is a URL prefix, but it also names the directory below
.web/build/client that the production build is relocated into (build.py)
and served from (exec.py). A ".." segment would move the built frontend
outside the build output, and since path_ops.mv removes existing
destinations, could overwrite neighboring files.

Validate this once in Config._normalize_paths so every consumer can trust
the value, rather than re-checking at each filesystem use.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UwbNDEaQNGWeHWS8nxsURd
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants