harry0703/MoneyPrinterTurbo · error · HttpException
{request_id}: Only files with extensions {', '.join(allowed_
Error message
{request_id}: Only files with extensions {', '.join(allowed_suffixes)} can be uploaded What it means
Raised by the video-material upload endpoint when the sanitized filename's suffix is not in allowed_suffixes. The preceding comment notes a fixed subtlety: suffix is checked as a proper extension (e.g. via Path suffix), so a bare-dots filename can't sneak past as it could with naive endswith('jpg'). Existing files with a matching name are overwritten by design ('If the file already exists, it will be overwritten').
Source
Thrown at app/controllers/v1/video.py:425
request_id = base.get_task_id(request)
safe_filename = _sanitize_upload_filename(file.filename, request_id)
# check file ext
allowed_suffixes = ("mp4", "mov", "avi", "flv", "mkv", "jpg", "jpeg", "png")
suffix = pathlib.Path(safe_filename).suffix.lower().lstrip(".")
# 按完整扩展名校验,既兼容 .MOV 这类大写后缀,也避免 photojpg 这种没有
# 点号的文件名因为 endswith("jpg") 被误当成合法图片。
if suffix in allowed_suffixes:
local_videos_dir = utils.storage_dir("local_videos", create=True)
save_path = os.path.join(local_videos_dir, safe_filename)
# save file
with open(save_path, "wb+") as buffer:
# If the file already exists, it will be overwritten
file.file.seek(0)
buffer.write(file.file.read())
response = {"file": safe_filename}
return utils.get_response(200, response)
raise HttpException(
"", status_code=400, message=f"{request_id}: Only files with extensions {', '.join(allowed_suffixes)} can be uploaded"
)
@router.get("/stream/{file_path:path}")
async def stream_video(request: Request, file_path: str):
request_id = base.get_task_id(request)
tasks_dir = utils.task_dir()
video_path = _resolve_path_within_directory(tasks_dir, file_path, request_id)
range_header = request.headers.get("Range")
video_size = os.path.getsize(video_path)
start, end = _parse_byte_range(range_header, video_size, request_id)
length = end - start + 1
def file_iterator(file_path, offset=0, bytes_to_read=None):
with open(file_path, "rb") as f:
f.seek(offset, os.SEEK_SET)
remaining = bytes_to_read or video_size
while remaining > 0:View on GitHub (pinned to 1f9f19c202)
Solutions
- Convert the clip to an allowed format before upload (e.g. ffmpeg -i in.mov -c:v libx264 -c:a aac out.mp4).
- Client-side pre-check: Path(filename).suffix.lower() in allowed_suffixes read from the same list the server uses.
- Make sure the filename has exactly one intended extension and no trailing dots/spaces.
Example fix
# before
files = {"file": ("holiday.mov", open("holiday.mov", "rb"))}
requests.post(url, files=files, headers=h)
# after
subprocess.run(["ffmpeg", "-y", "-i", "holiday.mov", "-c:v", "libx264", "-c:a", "aac", "holiday.mp4"], check=True)
files = {"file": ("holiday.mp4", open("holiday.mp4", "rb"))}
requests.post(url, files=files, headers=h) Defensive patterns
Strategy: validation
Validate before calling
from pathlib import Path
allowed = {".mp4", ".webm", ".jpg", ".jpeg", ".png"} # keep in sync with server
suffix = Path(filename).suffix.lower()
if suffix not in allowed:
raise ValueError(f"transcode first; allowed: {sorted(allowed)}") Type guard
def is_allowed_material(filename: str, allowed_suffixes: set[str]) -> bool:
return Path((filename or "").strip()).suffix.lower() in allowed_suffixes Prevention
- Restrict the client file picker to allowed extensions.
- Transcode phone/editor exports (HEVC/MOV) to MP4 before upload.
- Watch out for double extensions — only the final suffix counts.
When it happens
Trigger: POST /api/v1/video_materials with a .mov/.avi/.wmv (or any non-allowed) extension; a filename with no extension at all; a file named 'clip.mp4.exe' style double extensions where the final suffix fails the check.
Common situations: Users exporting clips from phone editors in HEVC (.mov) when only web-friendly formats are allowed; clients not validating extension before upload; uppercase-extension files if allowed_suffixes are lowercase-only.
Related errors
- {request_id}: invalid filename
- {request_id}: {str(exc)}
- unsupported background music format; supported formats: {sup
- unsupported local material type {extension or '<none>'}: {ma
- invalid background music filename
AI-assisted analysis of harry0703/MoneyPrinterTurbo@1f9f19c202 (2026-08-14).
Data as JSON: /api/errors/1aed004bf43e1e91.
Report an issue: GitHub.