Skip to content

fix(config): stop rx.asset in rxconfig.py from recursing - #7671

Open
vjymisal0 wants to merge 4 commits into
reflex-dev:mainfrom
vjymisal0:fix/asset-in-rxconfig-recursion
Open

vjymisal0 wants to merge 4 commits into
reflex-dev:mainfrom
vjymisal0:fix/asset-in-rxconfig-recursion

Conversation

@vjymisal0

Copy link
Copy Markdown
Contributor

Summary

Calling rx.asset(...) at the top level of rxconfig.py raises RecursionError.

AssetPathStr.__new__ calls get_config() to prepend frontend_path. During the first config load, the context has no config yet, so get_config() calls _get_config(). That pops rxconfig from sys.modules and imports it again (_load_config_lock is an RLock, so the same thread re-enters). The re-import calls rx.asset again, and the loop continues until the stack overflows.

Changes:

  • _get_config() sets _loading_config while it imports rxconfig.py (under _load_config_lock). If it is called again during that import, it returns Config(app_name="", _skip_plugins_checks=True) instead of importing the file again. This is the env and default config it already returns when no rxconfig.py exists.
  • get_config() does not cache that stand-in on the RegistrationContext. Without this, a load through _get_config() directly (or the deprecated _load_config()) would leave the context holding the stand-in.

Known limitation: an asset created in rxconfig.py before rx.Config(...) runs only sees frontend_path from the environment (REFLEX_FRONTEND_PATH) or the default. It cannot see a frontend_path passed to the rx.Config(...) call further down the same file, because that config does not exist yet.

Verification

  • New test test_get_config_inside_rxconfig_does_not_reload_it in tests/units/test_config.py:
    • On main it fails with RecursionError.
    • Without the get_config() no-cache branch, it fails with assert ctx._config is None.
    • With this change it passes.
  • The reproduction from the issue (ASSET = rx.asset("favicon.ico") above rx.Config(...)) now loads and returns '/favicon.ico?v=e3b0c442'.
  • uv run pytest tests/units/test_config.py: 160 passed.
  • uv run pytest tests/units: 12348 passed, 17 failed. The same 17 fail on main on my Windows machine: tests/units/assets shared-asset symlink tests, test_create_resolves_shared_asset and test_initialize_agents_md_handles_symlinked_claude. None of them are related to this change.
  • ruff check, ruff format --check and pyright are clean on the changed files.
  • Added the news fragment packages/reflex-base/news/7669.bugfix.md.

Closes #7669

rx.asset builds its URL with get_config(). Called at the top level of
rxconfig.py, that started a second config load, which imported
rxconfig.py again and recursed until RecursionError.

While rxconfig.py is importing, _get_config() now returns the env and
default config instead of importing it again, and get_config() does not
cache that stand-in on the context.

Signed-off-by: vjymisal0 <misalvijay153@gmail.com>
@vjymisal0
vjymisal0 requested a review from a team as a code owner October 27, 2026 13:18

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

View guided diff | Re-trigger cubic

@greptile-apps

greptile-apps Bot commented Oct 27, 2026 •

Copy link
Copy Markdown
Contributor

RetriggerView in GreptileConfidence Score: 5/5

[Medium impact] The PR appears safe to merge; no blocking issues remain.

Summary

Prevents rx.asset(...) in rxconfig.py from importing the config file again while it is already loading.

  • Early config reads no longer restart rxconfig.py imports.

The earlier finding about generated setters is fixed. No new actionable issues were found.

Reviews (4) · Last reviewed commit: "fix(config): restore state_auto_setters ..." · Reviewed by Greptile

@codspeed

codspeed Bot commented Oct 27, 2026 •

Copy link
Copy Markdown

Merging this PR will degrade performance by 5.07%

2 warnings

⚠️ 20 benchmarks are dominated by system calls

System calls cannot be simulated consistently and are left out of the measure. The reported value understates the real cost. Switch to the Walltime instrument to measure them.

Learn more about system calls

See affected benchmarks

⚠️ 2 benchmarks with a significant change ran on different hardware

Their base and head results were measured on machines with a different CPU, core count or memory, so the changes might not come from the code. Run base and head on the same runner type.

Learn more about Macro Runners

See affected benchmarks

❌ 2 regressed benchmarks
✅ 146 untouched benchmarks

Warning

Please fix the performance issues or acknowledge them on CodSpeed.

Performance Changes

Benchmark BASE HEAD Efficiency
❌ test_state_access[write_own] 127.5 ms 135.7 ms -6.06%
❌ test_on_event_router_data 1.9 ms 2 ms -4.06%

Tip

Investigate this regression by commenting @codspeedbot fix this regression on this PR, or directly use the CodSpeed MCP with your agent.


Comparing vjymisal0:fix/asset-in-rxconfig-recursion (0047270) with main (aeea15a)

Open in CodSpeed

@masenf masenf added the bug Something isn't working label Oct 27, 2026
…nd-in

Constructing the stand-in Config published its default
state_auto_setters, replacing the value a Config created earlier in
rxconfig.py had set. State classes defined later lost their generated
setters. Restore the published value after building the stand-in.

Signed-off-by: vjymisal0 <misalvijay153@gmail.com>

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

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

View guided diff | Re-trigger cubic

… fails

The mid-import stand-in Config publishes its state_auto_setters before
validation, so a ConfigError (e.g. redis mode without a redis URL) left
that value in place. Restore the saved value in a finally block.

Signed-off-by: vjymisal0 <misalvijay153@gmail.com>

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Recursion when using rx.asset in rxconfig on global scope

2 participants