langflow-ai/langflow · warning · HTTPException
Invalid flow filename
Error message
Invalid flow filename
What it means
Raised by _safe_resolved_path: after resolving the requested flow path with os.path.realpath and the flows base directory, the resolved path is neither the base itself nor under it (base + os.sep prefix). This is the path-traversal/symlink-escape guard (the pattern CodeQL's py/path-injection recognizes); any filename that escapes FLOWS_BASE_PATH — via '../', nested traversal, or a symlink inside the directory pointing outside — is rejected with HTTP 400.
Source
Thrown at src/backend/base/langflow/agentic/services/helpers/flow_loader.py:52
yield
finally:
sys.path.remove(path)
else:
yield
def _safe_resolved_path(flow_path: Path) -> Path:
"""Resolve *flow_path* and confirm it stays within FLOWS_BASE_PATH.
Uses ``os.path.realpath`` + ``startswith`` — the sanitiser pattern
recognised by CodeQL's ``py/path-injection`` analysis — so the
returned path is safe to pass to filesystem operations such as
``Path.exists()``. Raises HTTPException 400 on escape attempts.
"""
base_resolved = os.path.realpath(str(FLOWS_BASE_PATH))
resolved = os.path.realpath(str(flow_path))
if resolved != base_resolved and not resolved.startswith(base_resolved + os.sep):
raise HTTPException(status_code=400, detail="Invalid flow filename")
return Path(resolved)
def resolve_flow_path(flow_filename: str) -> tuple[Path, str]:
"""Resolve flow filename to path and determine type.
Supports both explicit extensions (.json, .py) and auto-detection.
Priority: explicit extension > .py > .json
Args:
flow_filename: Name of the flow file (with or without extension).
Returns:
tuple[Path, str]: (resolved path, file type: "json" or "python")
Raises:
HTTPException: If flow file not found.
"""View on GitHub (pinned to 976ec789d2)
Solutions
- Pass a bare filename (optionally with .json/.py) relative to FLOWS_BASE_PATH — no absolute paths, no '..'.
- On the server side, remove symlinks inside FLOWS_BASE_PATH that point outside the directory.
- In clients, strip/reject '..', backslashes, and leading '/' from flow_name before sending.
Example fix
// before
fetch(`/api/v1/agentic/execute/${encodeURIComponent('../../secrets/flow.json')}`)
// after
fetch(`/api/v1/agentic/execute/${encodeURIComponent('my-flow.json')}`) Defensive patterns
Strategy: validation
Validate before calling
from pathlib import Path
def safe_flow_name(name: str) -> bool:
return bool(name) and '..' not in name and '\\' not in name and not name.startswith('/') and Path(name).name == name Type guard
const isSafeFlowName = (n: string): boolean =>
/^[A-Za-z0-9_.-]+$/.test(n) && !n.includes('..'); Try / catch
On 400 'Invalid flow filename', log it as a potential attack/probe and never echo the requested name back to end users.
Prevention
- Whitelist flow names to a strict charset (letters, digits, dash, underscore, dot).
- Never build flow_name from raw user input or URL fragments.
- Keep FLOWS_BASE_PATH free of symlinks pointing outside itself.
When it happens
Trigger: Calling an agentic execute endpoint with flow_name like 'sub/../../etc/passwd', 'flows/../../../home/user/secret.json', or a filename that resolves through a symlink planted in the flows directory to a file outside it.
Common situations: Probing attacks against deployments that pass user input straight into flow_name; legitimate-looking names containing URL-encoded traversal that survived decoding; a symlinked flow file in the directory for 'shared' flows; copy-pasting an absolute path as flow_name.
Related errors
- Invalid flow filename: '{flow_filename}'
- Invalid path
- Invalid {label}. Use a simple {label} without directory path
- Invalid file entry
- Invalid file path format
AI-assisted analysis of langflow-ai/langflow@976ec789d2 (2026-08-14).
Data as JSON: /api/errors/3f20d12962bcd1e0.
Report an issue: GitHub.