reflex-dev/reflex · error · ReflexError
Memoized component modules {clash!r} and {module_name!r} bot
Error message
Memoized component modules {clash!r} and {module_name!r} both mirror to {module_path!r} (their paths differ only by case), which collides on case-insensitive filesystems. Rename one of the source modules. What it means
When compiling memoized components, Reflex mirrors internal modules into the .web directory keyed by module path. Two module names that differ only in case (e.g. mywidget and MyWidget) map to the same path on case-insensitive filesystems (macOS, Windows), which would silently collide, so compilation fails with a ReflexError asking for a rename.
Source
Thrown at reflex/compiler/compiler.py:554
_extend_imports_in_place(aggregate_imports, _MEMO_BASE_IMPORTS)
_apply_common_imports(aggregate_imports)
# Maps a case-folded output path to the module that claimed it, so two
# modules differing only by case (which collide on case-insensitive
# filesystems) are caught instead of one silently overwriting the other.
claimed_paths: dict[str, str] = {}
for segments, group in groups.items():
module_path = utils.get_memo_module_path(segments)
module_name = ".".join(segments)
case_key = module_path.casefold()
if (clash := claimed_paths.get(case_key)) is not None:
msg = (
f"Memoized component modules {clash!r} and {module_name!r} both "
f"mirror to {module_path!r} (their paths differ only by case), "
f"which collides on case-insensitive filesystems. Rename one of "
f"the source modules."
)
raise ReflexError(msg)
claimed_paths[case_key] = module_name
# Strip self-imports — when memos in this group reference each other,
# their compiled imports point at this group's own mirrored specifier.
# Importing from the same file would shadow the module's own exports.
self_specifier = memo_paths.mirrored_library_specifier(segments)
group.imports.pop(self_specifier, None)
merged_imports = utils.merge_imports(_MEMO_BASE_IMPORTS, group.imports)
_apply_common_imports(merged_imports)
code = templates.memo_components_template(
imports=utils.compile_imports(merged_imports),
components=group.components,
functions=group.functions,
dynamic_imports=sorted(set(group.dynamic_imports)),
custom_codes=list(dict.fromkeys(group.custom_code)),
)
output_files.append((module_path, code))
_extend_imports_in_place(aggregate_imports, group.imports)
View on GitHub (pinned to 45b8ed5ab7)
Solutions
- Find the two clashing module names printed in the error and rename one so the names differ by more than case
- Delete the stale/older module if it was left behind by a refactor
- Standardize on a single casing convention (snake_case modules) via lint/CI to prevent recurrence
Example fix
# before: components/Chart.py and components/chart.py both define @rx.memo components # after: rename one, e.g. components/chart.py -> components/chart_widget.py, update imports
Defensive patterns
Strategy: validation
Validate before calling
from pathlib import Path
def check_module_case_clash(pkg_dir: Path) -> None:
seen: dict[str, str] = {}
for p in sorted(pkg_dir.rglob("*.py")):
key = str(p.with_suffix("")).lower()
if key in seen:
raise ValueError(f"case clash: {seen[key]} vs {p}")
seen[key] = str(p) Prevention
- Use snake_case module names exclusively (PEP 8)
- Add a CI check that rejects module names differing only by case
- Delete stale modules after renames instead of leaving differently-cased copies
When it happens
Trigger: Having two memoized component modules in the same package whose names differ only by letter case — e.g. reflex/components/mywidget.py and reflex/components/MyWidget.py (or user modules in the app's pages/components tree) — both containing @rx.memo components that get compiled into mirrored libraries.
Common situations: Refactoring that renames a module leaving a differently-cased duplicate; mixed-case imports from different contributors on case-sensitive Linux dev boxes that then break macOS/Windows builds; copying a module and changing only case in the name.
Related errors
- ChildrenTypeError(component=cls.__name__, child=child)
- Do not override _add_style directly. Use add_style instead.
- The component `{comp_name}` cannot have `{child_name}` as a
- The component `{comp_name}` only allows the components: {val
- The component `{child_name}` can only be a child of the comp
AI-assisted analysis of reflex-dev/reflex@45b8ed5ab7 (2026-08-28).
Data as JSON: /api/errors/f3ce7af61a16d3df.
Report an issue: GitHub.