{"record":{"id":"c63ecdacfa3f699a","repo":"langflow-ai/langflow","slug":"invalid-path-e","errorCode":null,"errorMessage":"Invalid path: {e}","messagePattern":"Invalid path: (.+?)","errorType":"http","errorClass":"HTTPException","httpStatus":400,"severity":"error","filePath":"src/backend/base/langflow/api/v1/flows_helpers.py","lineNumber":96,"sourceCode":"    try:\n        base_dir_resolved = os.path.realpath(str(base_dir))\n    except (OSError, ValueError) as e:\n        raise HTTPException(status_code=400, detail=f\"Invalid base directory: {e}\") from e\n\n    # Determine if path is absolute (Unix or Windows style)\n    is_absolute = normalized_path.startswith(\"/\") or (len(normalized_path) > 1 and normalized_path[1] == \":\")\n\n    if is_absolute:\n        candidate = normalized_path\n    else:\n        relative_part = normalized_path.lstrip(\"/\")\n        # os.path.join is deliberate here (PTH118) to match CodeQL's sanitiser model.\n        candidate = os.path.join(base_dir_resolved, relative_part) if relative_part else base_dir_resolved  # noqa: PTH118\n\n    try:\n        resolved_str = os.path.realpath(candidate)\n    except (OSError, ValueError) as e:\n        raise HTTPException(status_code=400, detail=f\"Invalid path: {e}\") from e\n\n    # SECURITY: containment check using os.path.realpath + startswith (CodeQL-recognised).\n    if resolved_str != base_dir_resolved and not resolved_str.startswith(base_dir_resolved + os.sep):\n        if is_absolute:\n            raise HTTPException(\n                status_code=400,\n                detail=\"Absolute path must be within your flows directory\",\n            )\n        raise HTTPException(\n            status_code=400,\n            detail=\"Invalid path: resolves outside allowed directory\",\n        )\n\n    # Return the canonicalised path — safe for subsequent filesystem operations.\n    return Path(resolved_str)\n\n\n# Fields that may be updated via setattr on a Flow ORM instance.","sourceCodeStart":78,"sourceCodeEnd":114,"githubUrl":"https://github.com/langflow-ai/langflow/blob/976ec789d2886a86de109c044d089d68e96c9a35/src/backend/base/langflow/api/v1/flows_helpers.py#L78-L114","documentation":"HTTP 400: os.path.realpath() raised OSError/ValueError while canonicalising the CANDIDATE path (the client fs_path, or base_dir + relative part). Unlike the base-dir failure this one is usually caused by the submitted path itself being unresolvable on this host.","triggerScenarios":"fs_path containing embedded NULs that survived earlier checks, a path component that triggers OSError during realpath (permission denied walking a symlinked parent, path too long on Windows), or a ValueError from an ill-formed path string.","commonSituations":"Long nested fs_path values on Windows deployments; fs_path pointing through a symlink the backend user lacks permission to read; a client URL-decoding the payload incorrectly and injecting control characters.","solutions":["Shorten/flatten fs_path to a simple filename under the user's flows dir (e.g. \"my_flow.json\").","Inspect the exact fs_path bytes sent (hex dump) for stray control characters and fix client encoding.","On the server, check permissions on <data_dir>/flows/<user_id> and any symlinked parents.","Enable Windows long-path support if path length is the cause."],"exampleFix":"# before\n{\"fs_path\": \"projects/2026/very/deeply/nested/.../flow.json\"}  # >260 chars on Windows\n# after\n{\"fs_path\": \"flow-2026.json\"}","handlingStrategy":"validation","validationCode":"if (fsPath.length > 200) throw new Error('fs_path too long; use a flat filename');","typeGuard":"const isSafeLength = (p: string) => p.length <= 200 && !/[\\x00-\\x1f]/.test(p);","tryCatchPattern":null,"preventionTips":["Prefer flat filenames over deep sub-paths","Check backend user permissions on the flows directory","Enable Windows long-path support"],"tags":["filesystem","validation","http-400","fs-path","windows"],"backgroundTag":null,"analyzedSha":"976ec789d2886a86de109c044d089d68e96c9a35","analyzedAt":"2026-08-14T18:23:12.227Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}