langflow-ai/langflow · error · UserComponentError
str(exc)
Error message
str(exc)
What it means
Raised when _resolve_components_dir's call to FileSystemToolComponent._validate_root() raises PermissionError, and the message is re-wrapped as UserComponentError(str(exc)). Two documented causes: (1) AUTO_LOGIN=False and no user_id was supplied — the sandbox resolver refuses to pick a shared root in that mode; (2) sandbox configuration or disk failure inside the resolver. The original message text is preserved verbatim.
Source
Thrown at src/backend/base/langflow/agentic/services/user_components.py:264
def _resolve_components_dir(*, user_id: str | None) -> Path:
"""Resolve and create ``<sandbox>/.components/`` for the given user.
Reuses the FS tool's authoritative sandbox resolver so the hash
function, pepper handling, AUTO_LOGIN dispatch, and no-user refusal
stay in one place. The reserved-segment guard does NOT apply here —
this helper is the privileged writer that the guard is protecting.
"""
component = FileSystemToolComponent()
if user_id is not None:
component._user_id = user_id # noqa: SLF001 — privileged binding seam
try:
sandbox_root = component._validate_root() # noqa: SLF001
except PermissionError as exc:
# PermissionError from _validate_root happens in two cases:
# 1. AUTO_LOGIN=False and no user_id → translate to our domain error.
# 2. Sandbox config / disk failure → re-wrap so callers see the
# same single-class refusal envelope.
raise UserComponentError(str(exc)) from exc
components_dir = sandbox_root / ".components"
try:
components_dir.mkdir(parents=True, exist_ok=True)
except OSError as exc:
msg = f"Cannot create .components directory: {exc.strerror or exc}"
raise UserComponentError(msg) from exc
return components_dir
def _atomic_write_text(target: Path, text: str) -> None:
"""Write ``text`` to ``target`` via a tmp file + os.replace rename.
On any failure, removes the tmp file so the directory never
accumulates stray ``.tmp`` artifacts. ``os.replace`` is atomic on
POSIX and on Windows (since Python 3.3) when source and dest are on
the same filesystem — which they are here, both inside the user's
sandbox.View on GitHub (pinned to 976ec789d2)
Solutions
- Pass a real user_id when AUTO_LOGIN=False — each user gets their own hashed sandbox directory.
- If a user_id was passed, inspect the wrapped PermissionError message: it names the actual sandbox config problem.
- Verify the sandbox base directory exists and is writable by the backend process, and that the pepper file is intact.
Example fix
# before (AUTO_LOGIN=False) register_user_component(user_id=None, class_name="MyTool", code=src) # after register_user_component(user_id=str(current_user.id), class_name="MyTool", code=src)
Defensive patterns
Strategy: validation
Validate before calling
def can_resolve_user_sandbox(user_id: str | None, auto_login: bool) -> bool:
return user_id is not None or auto_login Try / catch
try:
register_user_component(user_id=user_id, class_name=name, code=src)
except UserComponentError as e:
if "permission" in str(e).lower() or "user" in str(e).lower():
log_config_problem(str(e)) # message is the original PermissionError text Prevention
- Always bind a user_id before calling registration in multi-user (AUTO_LOGIN=False) deployments.
- Health-check the sandbox base dir and pepper file at startup.
When it happens
Trigger: Calling register_user_component(user_id=None) while the deployment runs with AUTO_LOGIN=False; or a corrupted/missing sandbox base dir, unreadable pepper file, or permission problem on the configured BASE_DIR.
Common situations: Background/worker contexts where no authenticated user is bound; env var LANGFLOW_AUTO_LOGIN toggled between environments; sandbox root moved or its permissions changed after deployment.
Related errors
- Cannot create .components directory: {exc.strerror or exc}
- Not found
- err
- class_name must be a CamelCase identifier (letters/digits/un
- class_name {class_name!r} is a Windows-reserved device name
AI-assisted analysis of langflow-ai/langflow@976ec789d2 (2026-08-14).
Data as JSON: /api/errors/46f445207bf63533.
Report an issue: GitHub.