harry0703/MoneyPrinterTurbo · error · ValueError
unsupported background music path
Error message
unsupported background music path
What it means
Raised by resolve_bgm_file as a ValueError when the supplied path is falsy (empty/None) or its lowercase extension is not in SUPPORTED_BGM_EXTENSIONS (.mp3 .m4a .aac .wav .flac .ogg .opus .wma, app/services/bgm.py:28). This is an input-shape check done before any directory whitelisting, so garbage paths fail fast with an unambiguous reason. MoviePy ultimately decodes via FFmpeg, but only these mainstream audio extensions are accepted to avoid treating video containers as BGM.
Source
Thrown at app/services/bgm.py:315
)
continue
files_by_name[name] = resolved_path
return [files_by_name[name] for name in sorted(files_by_name, key=str.lower)]
def resolve_bgm_file(unsafe_path: str) -> str:
"""
在用户上传目录和内置歌曲目录中解析 BGM,并拒绝两个白名单之外的路径。
文件名优先命中用户目录,同时保留 `output000.mp3`、绝对白名单路径和
`./resource/songs/output000.mp3` 等旧用法。新上传文件使用 UUID,正常情况下
不会与内置歌曲或历史上传发生重名。
"""
if (
not unsafe_path
or Path(unsafe_path).suffix.lower() not in SUPPORTED_BGM_EXTENSIONS
):
raise ValueError("unsupported background music path")
candidates = [unsafe_path]
if not os.path.isabs(unsafe_path):
candidates.append(os.path.join(utils.root_dir(), unsafe_path))
last_error = ValueError("background music file does not exist")
for directory in (uploaded_bgm_dir(create=True), utils.song_dir()):
for candidate in candidates:
try:
return file_security.resolve_path_within_directory(directory, candidate)
except ValueError as exc:
last_error = exc
raise ValueError(str(last_error)) from last_error
View on GitHub (pinned to 1f9f19c202)
Solutions
- Fix the path to reference one of the supported audio formats (convert with FFmpeg if needed).
- If a broader format is required, extend SUPPORTED_BGM_EXTENSIONS in app/services/bgm.py — it is the single source of truth also feeding the WebUI upload control.
- Normalize/validate stored BGM paths at write time (config save) so resolve never sees unsupported extensions.
Example fix
// before
resolve_bgm_file('intro.mp4')
// after
subprocess.run(['ffmpeg', '-i', 'intro.mp4', '-vn', 'intro.mp3'])
resolve_bgm_file('intro.mp3') Defensive patterns
Strategy: validation
Validate before calling
from app.services.bgm import SUPPORTED_BGM_EXTENSIONS
def is_acceptable_bgm_path(path: str) -> bool:
return bool(path) and Path(path).suffix.lower() in SUPPORTED_BGM_EXTENSIONS Type guard
from pathlib import Path
from app.services.bgm import SUPPORTED_BGM_EXTENSIONS
def is_supported_bgm_path(unsafe_path: str) -> bool:
"""True when the path has a non-empty supported audio extension."""
return bool(unsafe_path) and Path(unsafe_path).suffix.lower() in SUPPORTED_BGM_EXTENSIONS Try / catch
try:
resolve_bgm_file(path)
except ValueError as e:
if 'unsupported background music path' in str(e):
# convert or fall back to a built-in song
path = 'output000.mp3' Prevention
- Restrict the file picker/playlist to SUPPORTED_BGM_EXTENSIONS at selection time.
- Validate paths when saving task config, not only when resolving.
- Convert exotic formats (AIFF, WV, video files) to whitelisted audio formats before registering them.
When it happens
Trigger: Calling resolve_bgm_file with '', None, a path like 'song.mp4' or 'track', or any extension outside the 8-entry whitelist. The check runs before the uploaded-dir and song-dir resolution loop.
Common situations: Stale config or DB rows referencing files renamed to a new extension; playlists containing .wv/.aiff/.m4p files; passing a video filename by mistake; legacy values like 'output000' without extension.
Related errors
- unsupported background music format; supported formats: {sup
- {request_id}: {str(exc)}
- {request_id}: background music validation is unavailable
- {request_id}: Only files with extensions {', '.join(allowed_
- invalid background music filename
AI-assisted analysis of harry0703/MoneyPrinterTurbo@1f9f19c202 (2026-08-14).
Data as JSON: /api/errors/c4f3150bea14a9eb.
Report an issue: GitHub.