harry0703/MoneyPrinterTurbo · error · HttpException
{request_id}: invalid file path
Error message
{request_id}: invalid file path What it means
Raised by _resolve_path_within_directory in app/controllers/v1/video.py when file_security.resolve_path_within_directory rejects the caller-supplied path relative to the task directory. The status is 404 when the underlying error is 'file does not exist' and 403 for any other failure (typically path traversal outside base_dir). The response text is deliberately stable ('{request_id}: invalid file path') so server paths don't leak.
Source
Thrown at app/controllers/v1/video.py:86
normalized_name = (filename or "").replace("\\", "/").split("/")[-1].strip()
if not normalized_name or normalized_name in {".", ".."}:
raise HttpException(
task_id=request_id,
status_code=400,
message=f"{request_id}: invalid filename",
)
return normalized_name
def _resolve_path_within_directory(base_dir: str, unsafe_path: str, request_id: str) -> str:
try:
return file_security.resolve_path_within_directory(base_dir, unsafe_path)
except ValueError as exc:
logger.warning(
f"reject unsafe file path, request_id: {request_id}, path: {unsafe_path}, "
f"error: {str(exc)}"
)
raise HttpException(
task_id=request_id,
status_code=404 if str(exc) == "file does not exist" else 403,
message=f"{request_id}: invalid file path",
)
def _public_task_data(task: dict) -> dict:
"""复制任务状态并移除仅用于服务端进程协调的内部字段。"""
public_task = dict(task)
public_task.pop("cross_post_owner", None)
return public_task
def _task_file_to_uri(file: str, endpoint: str, task_dir: str, request_id: str) -> str:
if not isinstance(file, str):
return file
if file.startswith(("http://", "https://")):View on GitHub (pinned to 1f9f19c202)
Solutions
- Only use stream URIs exactly as returned by the API (the tasks/{task_id}/... paths from task responses); never construct them by hand.
- If you get 404, re-fetch the task to confirm it and its artifacts still exist; regenerate if the task was deleted.
- If you get 403, remove any ../ or leading-slash components from the path you are passing.
- Handle 404 by refreshing task state instead of retrying the same stale path.
Example fix
# before
video_uri = f"tasks/{task_id}/../../etc/passwd"
# after
resp = requests.get(f"{base}/api/v1/tasks/{task_id}", headers=h).json()
video_uri = resp[\"data\"][\"videos\"][0] # server-issued, already-safe relative path Defensive patterns
Strategy: validation
Validate before calling
# client: only consume server-issued relative URIs
task = requests.get(f"{base}/api/v1/tasks/{task_id}", headers=h).json()["data"]
uri = task["videos"][0]
assert not uri.startswith("/") and ".." not in uri # sanity-check server-issued path Type guard
def is_relative_task_path(p: str) -> bool:
return bool(p) and not p.startswith(("/", "\\")) and ".." not in p.replace("\\", "/").split("/") Try / catch
try:
stream(url)
except HTTPError as e:
if e.response.status_code == 404:
refresh_task_state(task_id) # artifact/task gone
elif e.response.status_code == 403:
raise RuntimeError("stream path rejected; use server-issued URIs only") from e
raise Prevention
- Never build stream paths yourself; always use the URI from the task response.
- Refresh task state after receiving 404 instead of retrying the same path.
- URL-encode the path exactly once; double-encoding can turn into traversal-looking input.
When it happens
Trigger: GET /api/v1/stream/<path> where path contains ../ sequences escaping the tasks directory (403); streaming a file whose task directory or artifact no longer exists (404); URL-encoded traversal like %2e%2e%2f; referencing an artifact belonging to a deleted task.
Common situations: Stale client-held URIs after a task was deleted or its directory cleaned; hand-crafted or fuzzed URLs probing for traversal; double-encoding bugs in a frontend router that mangles the relative path.
Related errors
- {request_id}: invalid filename
- {request_id}: requested range is not satisfiable
- {request_id}: task not found
- ElevenLabs audio exceeds the 50 MB limit
- failed to request ElevenLabs music: {exc}
AI-assisted analysis of harry0703/MoneyPrinterTurbo@1f9f19c202 (2026-08-14).
Data as JSON: /api/errors/ccacd8202ecf726f.
Report an issue: GitHub.