reflex-dev/reflex · error · InvalidPluginConfigError
reflex.Config.plugins contains plugin(s) that could not be l
Error message
reflex.Config.plugins contains plugin(s) that could not be loaded (check REFLEX_PLUGINS import paths): {details}. What it means
One or more plugin instances loaded via the `REFLEX_PLUGINS` environment variable could not be imported/instantiated — their `describe()` output (usually the import path and error) is included in the message. This validation happens after merging env-var plugins into `Config.plugins`.
Source
Thrown at packages/reflex-base/src/reflex_base/config.py:474
f"reflex.Config.plugins entry {entry.__name__!r} could not be "
f"instantiated and may require arguments; pass an instance "
f"instead, e.g. plugins=[{entry.__name__}(...)]."
)
raise InvalidPluginConfigError(msg) from exc
else:
msg = (
f"reflex.Config.plugins must contain Plugin instances, but got "
f"{entry!r} of type {type(entry).__name__}. "
f"Pass an instance, e.g. plugins=[SitemapPlugin()]."
)
raise InvalidPluginConfigError(msg)
if invalid:
details = ", ".join(p.describe() for p in invalid)
msg = (
f"reflex.Config.plugins contains plugin(s) that could not be loaded "
f"(check REFLEX_PLUGINS import paths): {details}."
)
raise InvalidPluginConfigError(msg)
self.plugins = normalized
def _add_extra_plugins(self):
"""Append plugins declared via the ``REFLEX_EXTRA_PLUGINS`` env var.
Unlike ``REFLEX_PLUGINS``, which *replaces* ``plugins`` entirely, this env
var appends to the existing list so plugins configured in ``rxconfig.py``
are preserved. Each entry is a fully qualified import path resolved to a
Plugin *subclass* (not instantiated by the env machinery). For each class:
- An invalid import path is warned about and skipped (a bad env entry is
never fatal, since the app still has its configured plugins).
- A type listed in ``disable_plugins`` is skipped *without* instantiating
it, so a disabled plugin never runs its constructor.
- A type already present in ``plugins`` is skipped, so a plugin is never
run twice.
- Otherwise the class is instantiated and appended; a constructor failure
is warned about and skipped.View on GitHub (pinned to 45b8ed5ab7)
Solutions
- Check each path in REFLEX_PLUGINS and verify the module imports cleanly (`uv run python -c "import myapp.plugins"`)
- Fix the moved/renamed module or update the env var to the new path
- Install missing dependencies the plugin needs
- Remove the env var entry if the plugin is no longer used
Example fix
# before REFLEX_PLUGINS=myapp.old_plugin_path # after REFLEX_PLUGINS=myapp.plugins.sitemap
Defensive patterns
Strategy: validation
Validate before calling
import importlib
def plugins_importable(paths: list[str]) -> None:
for p in paths:
importlib.import_module(p) # raises early with a clear ImportError
plugins_importable(os.environ.get("REFLEX_PLUGINS", "").split(",")) Try / catch
from reflex_base.config import InvalidPluginConfigError
try:
app = rx.App()
except InvalidPluginConfigError as e:
if "could not be loaded" in str(e):
os.environ.pop("REFLEX_PLUGINS", None)
app = rx.App() # boot without optional plugins
else:
raise Prevention
- Import-test every REFLEX_PLUGINS path in CI so moves/renames break the build, not prod
- Keep plugin modules dependency-light and pinned
- Remove stale entries from deployment env vars after refactors
When it happens
Trigger: REFLEX_PLUGINS points at a module path that no longer exists, raises on import (syntax error, missing dependency), or the plugin class moved/renamed.
Common situations: Refactoring moved a plugin module, a deployed environment missing a dependency used by a plugin, or stale env var values left in CI/deployment config.
Related errors
- reflex.Config.plugins entry {entry.__name__!r} could not be
- reflex.Config.plugins must contain Plugin instances, but got
- {self._prefixes[0]}REDIS_URL is required when using the redi
- default_color_mode must be one of {allowed_color_modes}, but
- Cached var {self!s} cannot access arbitrary state `{instruct
AI-assisted analysis of reflex-dev/reflex@45b8ed5ab7 (2026-08-28).
Data as JSON: /api/errors/44d2266909282645.
Report an issue: GitHub.