{"record":{"id":"46f445207bf63533","repo":"langflow-ai/langflow","slug":"str-exc","errorCode":null,"errorMessage":"str(exc)","messagePattern":"str\\(exc\\)","errorType":"validation","errorClass":"UserComponentError","httpStatus":null,"severity":"error","filePath":"src/backend/base/langflow/agentic/services/user_components.py","lineNumber":264,"sourceCode":"def _resolve_components_dir(*, user_id: str | None) -> Path:\n    \"\"\"Resolve and create ``<sandbox>/.components/`` for the given user.\n\n    Reuses the FS tool's authoritative sandbox resolver so the hash\n    function, pepper handling, AUTO_LOGIN dispatch, and no-user refusal\n    stay in one place. The reserved-segment guard does NOT apply here —\n    this helper is the privileged writer that the guard is protecting.\n    \"\"\"\n    component = FileSystemToolComponent()\n    if user_id is not None:\n        component._user_id = user_id  # noqa: SLF001 — privileged binding seam\n    try:\n        sandbox_root = component._validate_root()  # noqa: SLF001\n    except PermissionError as exc:\n        # PermissionError from _validate_root happens in two cases:\n        # 1. AUTO_LOGIN=False and no user_id → translate to our domain error.\n        # 2. Sandbox config / disk failure → re-wrap so callers see the\n        #    same single-class refusal envelope.\n        raise UserComponentError(str(exc)) from exc\n\n    components_dir = sandbox_root / \".components\"\n    try:\n        components_dir.mkdir(parents=True, exist_ok=True)\n    except OSError as exc:\n        msg = f\"Cannot create .components directory: {exc.strerror or exc}\"\n        raise UserComponentError(msg) from exc\n    return components_dir\n\n\ndef _atomic_write_text(target: Path, text: str) -> None:\n    \"\"\"Write ``text`` to ``target`` via a tmp file + os.replace rename.\n\n    On any failure, removes the tmp file so the directory never\n    accumulates stray ``.tmp`` artifacts. ``os.replace`` is atomic on\n    POSIX and on Windows (since Python 3.3) when source and dest are on\n    the same filesystem — which they are here, both inside the user's\n    sandbox.","sourceCodeStart":246,"sourceCodeEnd":282,"githubUrl":"https://github.com/langflow-ai/langflow/blob/976ec789d2886a86de109c044d089d68e96c9a35/src/backend/base/langflow/agentic/services/user_components.py#L246-L282","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"# before (AUTO_LOGIN=False)\nregister_user_component(user_id=None, class_name=\"MyTool\", code=src)\n\n# after\nregister_user_component(user_id=str(current_user.id), class_name=\"MyTool\", code=src)","handlingStrategy":"validation","validationCode":"def can_resolve_user_sandbox(user_id: str | None, auto_login: bool) -> bool:\n    return user_id is not None or auto_login","typeGuard":null,"tryCatchPattern":"try:\n    register_user_component(user_id=user_id, class_name=name, code=src)\nexcept UserComponentError as e:\n    if \"permission\" in str(e).lower() or \"user\" in str(e).lower():\n        log_config_problem(str(e))  # message is the original PermissionError text","preventionTips":["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."],"tags":["sandbox","permissions","auto-login","user-components"],"backgroundTag":null,"analyzedSha":"976ec789d2886a86de109c044d089d68e96c9a35","analyzedAt":"2026-08-14T18:23:12.227Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}