{"record":{"id":"c4f3150bea14a9eb","repo":"harry0703/MoneyPrinterTurbo","slug":"unsupported-background-music-path","errorCode":null,"errorMessage":"unsupported background music path","messagePattern":"unsupported background music path","errorType":"exception","errorClass":"ValueError","httpStatus":400,"severity":"error","filePath":"app/services/bgm.py","lineNumber":315,"sourceCode":"                )\n                continue\n            files_by_name[name] = resolved_path\n    return [files_by_name[name] for name in sorted(files_by_name, key=str.lower)]\n\n\ndef resolve_bgm_file(unsafe_path: str) -> str:\n    \"\"\"\n    在用户上传目录和内置歌曲目录中解析 BGM，并拒绝两个白名单之外的路径。\n\n    文件名优先命中用户目录，同时保留 `output000.mp3`、绝对白名单路径和\n    `./resource/songs/output000.mp3` 等旧用法。新上传文件使用 UUID，正常情况下\n    不会与内置歌曲或历史上传发生重名。\n    \"\"\"\n    if (\n        not unsafe_path\n        or Path(unsafe_path).suffix.lower() not in SUPPORTED_BGM_EXTENSIONS\n    ):\n        raise ValueError(\"unsupported background music path\")\n\n    candidates = [unsafe_path]\n    if not os.path.isabs(unsafe_path):\n        candidates.append(os.path.join(utils.root_dir(), unsafe_path))\n\n    last_error = ValueError(\"background music file does not exist\")\n    for directory in (uploaded_bgm_dir(create=True), utils.song_dir()):\n        for candidate in candidates:\n            try:\n                return file_security.resolve_path_within_directory(directory, candidate)\n            except ValueError as exc:\n                last_error = exc\n    raise ValueError(str(last_error)) from last_error\n","sourceCodeStart":297,"sourceCodeEnd":329,"githubUrl":"https://github.com/harry0703/MoneyPrinterTurbo/blob/1f9f19c2021a68d04df228f33e9099a0c947f6f8/app/services/bgm.py#L297-L329","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nresolve_bgm_file('intro.mp4')\n\n// after\nsubprocess.run(['ffmpeg', '-i', 'intro.mp4', '-vn', 'intro.mp3'])\nresolve_bgm_file('intro.mp3')","handlingStrategy":"validation","validationCode":"from app.services.bgm import SUPPORTED_BGM_EXTENSIONS\n\ndef is_acceptable_bgm_path(path: str) -> bool:\n    return bool(path) and Path(path).suffix.lower() in SUPPORTED_BGM_EXTENSIONS","typeGuard":"from pathlib import Path\nfrom app.services.bgm import SUPPORTED_BGM_EXTENSIONS\n\ndef is_supported_bgm_path(unsafe_path: str) -> bool:\n    \"\"\"True when the path has a non-empty supported audio extension.\"\"\"\n    return bool(unsafe_path) and Path(unsafe_path).suffix.lower() in SUPPORTED_BGM_EXTENSIONS","tryCatchPattern":"try:\n    resolve_bgm_file(path)\nexcept ValueError as e:\n    if 'unsupported background music path' in str(e):\n        # convert or fall back to a built-in song\n        path = 'output000.mp3'","preventionTips":["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."],"tags":["bgm","path-validation","file-extension","value-error"],"backgroundTag":null,"analyzedSha":"1f9f19c2021a68d04df228f33e9099a0c947f6f8","analyzedAt":"2026-08-14T19:41:05.568Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}