Skip to content

fail loudly when the app package has no __init__.py - #7304

Merged
FarhanAliRaza merged 11 commits into
reflex-dev:mainfrom
flcrom:fix/app-package-init-mismatch
Oct 9, 2026
Merged

FarhanAliRaza merged 11 commits into
reflex-dev:mainfrom
flcrom:fix/app-package-init-mismatch

Conversation

@flcrom

@flcrom flcrom commented Sep 24, 2026 •

Copy link
Copy Markdown
Contributor

Fixes #7258

The granian backend gets the app as a file path, and granian works out the module name by walking up through directories that have an __init__.py. When myapp/myapp/__init__.py is missing it imports the app as myapp instead of myapp.myapp. The compiler used myapp.myapp, so the root state names don't match and every delta gets dropped on the client.

get_app_file() now checks that each package in the app module path has an __init__.py and raises a clear error pointing at the missing file, instead of starting a backend that looks fine but never updates.

Tests cover the missing-init layouts (including a package-style app_module_import) and check that granian resolves the app file to the configured module name for valid layouts. Ran the unit suite, ruff, and pyright on the touched packages locally (full-repo pyright ran out of memory on my machine).

Review in cubic

@flcrom
flcrom requested a review from a team as a code owner September 24, 2026 10:12
@greptile-apps

greptile-apps Bot commented Sep 24, 2026 •

Copy link
Copy Markdown
Contributor

RetriggerConfidence Score: 4/5

[High impact] Changes how the backend app module is loaded and resolved.

The backend change appears safe, but the required test-function docstring should be added before merging.

Findings

  1. P2 Missing test docstring ▶

Summary

The PR switches Granian’s backend target from an app file path to the configured module name while retaining app-file validation. It adds regression tests for namespace-style app layouts, missing modules, and project-root imports.

Reviews (8) · Last reviewed commit: "Merge main into PR #7304 to refresh requ..." · Reviewed by Greptile

@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 news/7258.bugfix.md Outdated
@codspeed

codspeed Bot commented Sep 24, 2026 •

Copy link
Copy Markdown

Merging this PR will not alter performance

✅ 150 untouched benchmarks
⏩ 18 skipped benchmarks1


Comparing flcrom:fix/app-package-init-mismatch (f9000a3) with main (38a30fc)

Open in CodSpeed

Footnotes

  1. 18 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. ↩

Comment thread reflex/utils/exec.py Outdated
@flcrom

flcrom commented Sep 29, 2026

Copy link
Copy Markdown
Contributor Author

Updated this to create the missing __init__.py files before the backend import, while leaving existing files untouched. The regression tests cover nested packages, an app package, existing files, and an invalid marker path. Full unit suite, lint, and pyright pass locally. Could you take another look?

@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 (changes from recent commits).

You’re at about 90% of the monthly reviewed-line limit. You may want to disable incremental reviews to conserve quota. Reviews will continue until that limit is exceeded. If you need help avoiding interruptions, please contact contact@cubic.dev.

Tip: Review your code locally with the cubic CLI to iterate faster.

Re-trigger cubic

Comment thread news/7258.bugfix.md Outdated
Comment thread reflex/utils/exec.py Outdated
Comment thread reflex/utils/exec.py Outdated

@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 2 files (changes from recent commits).

You’re at about 90% of the monthly reviewed-line limit. You may want to disable incremental reviews to conserve quota. Reviews will continue until that limit is exceeded. If you need help avoiding interruptions, please contact contact@cubic.dev.

Tip: Review your code locally with the cubic CLI to iterate faster.

Re-trigger cubic

Comment thread reflex/utils/exec.py Outdated
Comment thread tests/units/utils/test_exec.py Outdated
Comment thread reflex/utils/exec.py Outdated
Comment thread reflex/utils/exec.py Outdated

@FarhanAliRaza FarhanAliRaza 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.

I tested this PR with a small app. The app has a root state and a substate, and its app package has no __init__.py.

On the base commit, I reproduced #7258. Clicks did not update the page, and the browser console showed the no dispatch function for substate(s) error.

On this branch, the bug is fixed in dev mode and in prod mode. The backend created the missing __init__.py in the app source tree and did not log a message.

I then changed only the Granian target on the base commit to the module name. That change also fixed the bug, and it wrote no file. Hot reload and the existing tests still passed.

The requested change is in the inline comment.

@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 4 files (changes from recent commits).

You’re at about 91% of the monthly reviewed-line limit. You may want to disable incremental reviews to conserve quota. Reviews will continue until that limit is exceeded. If you need help avoiding interruptions, please contact contact@cubic.dev.

Requires human review: Auto-approval blocked because this review re-detected 1 unresolved issue already reported by Cubic.
Tip: Review your code locally with the cubic CLI to iterate faster.

Re-trigger cubic

Comment thread reflex/utils/exec.py
Comment thread tests/units/utils/test_granian_module_target.py
Comment thread reflex/utils/exec.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 2 files (changes from recent commits).

You’re at about 91% of the monthly reviewed-line limit. You may want to disable incremental reviews to conserve quota. Reviews will continue until that limit is exceeded. If you need help avoiding interruptions, please contact contact@cubic.dev.

Tip: Review your code locally with the cubic CLI to iterate faster.

Re-trigger cubic

Comment thread tests/units/utils/test_granian_module_target.py
@masenf masenf added the bug Something isn't working label Oct 6, 2026
@masenf masenf added the on deck PRs lined up to review / merge next label Oct 9, 2026 — with ChatGPT Codex Connector
Comment thread tests/units/utils/test_granian_module_target.py
@FarhanAliRaza
FarhanAliRaza merged commit 162e5ef into reflex-dev:main Oct 9, 2026
146 checks passed
masenf pushed a commit that referenced this pull request Oct 23, 2026
#7304 ended up passing Granian the configured module target, so the
original fragment was accurate. The start method variables are only read
on the Granian code paths.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016T8wWv8bUUSzRHNGpKbSqW
masenf added a commit that referenced this pull request Oct 23, 2026
#7646)

* Correct 0.10.1 news fragments and document REFLEX_BACKEND_START_METHOD

The 7258 fragment described the opposite of what #7304 does (it raises an
error for a missing __init__.py instead of loading the app), the repeated
headers fragment still claimed client_ip came from the first x-forwarded-for
hop after #7614 made that depend on trusted_proxy_hops, and the 7261 fragment
belonged to a docs-only change. Add the backend start method variables to the
self-hosting docs; they were only described in environment.py.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016T8wWv8bUUSzRHNGpKbSqW

* Keep the 7258 fragment and scope the start method docs to Granian

#7304 ended up passing Granian the configured module target, so the
original fragment was accurate. The start method variables are only read
on the Granian code paths.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016T8wWv8bUUSzRHNGpKbSqW

---------

Co-authored-by: Claude <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working on deck PRs lined up to review / merge next

Projects

None yet

3 participants