langflow-ai/langflow · error · HTTPException
Invalid path
Error message
Invalid path
What it means
The agentic file-read router validates the requested path shape before any I/O: traversal ('..'), absolute paths, null bytes, and similar malformed shapes raise HTTP 400 'Invalid path'. This is _is_unsafe_path_shape rejecting the string itself, independent of whether the file exists. It uses the same security primitives as the agent's FileSystemToolComponent rather than a parallel implementation.
Source
Thrown at src/backend/base/langflow/agentic/api/files_router.py:115
*,
current_user: CurrentActiveUser,
path: Annotated[str, Query(min_length=1, max_length=_MAX_PATH_LENGTH)],
download: Annotated[bool, Query()] = False,
) -> Response:
"""Return the contents of a sandboxed file as text (or as an attachment).
Raises:
HTTPException(400): The path shape is invalid (traversal, absolute,
null byte, etc.). No I/O is attempted.
HTTPException(404): The file does not exist in the requesting user's
sandbox. Same status for sandbox-internal "not found" and for
"path resolves outside the user namespace" — by design, to avoid
leaking namespace existence to another tenant.
HTTPException(413): The file is larger than ``MAX_FILE_SIZE_BYTES``.
HTTPException(415): The file is binary (null byte in the first 8 KiB).
"""
if _is_unsafe_path_shape(path):
raise HTTPException(status_code=400, detail="Invalid path")
# Deferred import: FileSystemToolComponent pulls a chunk of lfx — we don't
# want every router-import path to do it eagerly. We use the **same**
# security primitives the agent's tools use, not a parallel implementation.
from lfx.components.files_and_knowledge.filesystem import (
BINARY_SNIFF_BYTES,
MAX_FILE_SIZE_BYTES,
FileSystemToolComponent,
_looks_binary,
_read_bytes_no_follow,
_read_head_no_follow,
)
fs = FileSystemToolComponent()
fs._user_id = str(current_user.id) # noqa: SLF001 — bind sandbox to caller
# B1: this endpoint carries an authenticated user identity and must
# always resolve a per-user sandbox root, even under AUTO_LOGIN=True
# (otherwise two users on a shared deployment read the same `shared/`View on GitHub (pinned to 976ec789d2)
Solutions
- Send a relative path under the user's sandbox, e.g. 'notes/todo.md' with no leading '/' and no '..' segments.
- Normalize client-side: strip absolute prefixes and reject '..' before calling the API.
- Treat 400 as a client bug — fix the path producer (often the model/tool prompt) rather than retrying.
Example fix
# before GET /api/v1/agentic/files?path=/home/user/sandbox/notes.md # 400 Invalid path # after GET /api/v1/agentic/files?path=notes.md
Defensive patterns
Strategy: validation
Validate before calling
from pathlib import PurePosixPath
def safe_sandbox_path(p: str) -> bool:
if not p or "\x00" in p:
return False
pp = PurePosixPath(p)
return not pp.is_absolute() and not any(part in ("..", "") for part in pp.parts) and "\\" not in p Try / catch
if resp.status_code == 400 and resp.json().get("detail") == "Invalid path":
log_and_sanitize_the_path_producer() # fix the generator (often LLM output), don't retry Prevention
- Always send relative POSIX paths with no '..' segments.
- Sanitize LLM/tool output before it becomes a path parameter.
- Treat 400 Invalid path as a client-side defect, never a server issue.
When it happens
Trigger: GET /api/v1/agentic/files?path=../../etc/passwd, path=/etc/hosts (absolute), or a path containing a null byte.
Common situations: LLM-generated tool output containing absolute or traversal paths fed straight into the API; clients joining user input with an OS path separator producing a leading slash; probing/pen-test payloads.
Related errors
- Provider '{provider}' is not configured. Available providers
- Could not extract class name from code
- Inputs and outputs have overlapping names: {overlap}
- Invalid flow filename
- Invalid flow filename: '{flow_filename}'
AI-assisted analysis of langflow-ai/langflow@976ec789d2 (2026-08-14).
Data as JSON: /api/errors/60e5ca38c276d63a.
Report an issue: GitHub.