{"record":{"id":"5028469b6a313da3","repo":"harry0703/MoneyPrinterTurbo","slug":"background-music-file-does-not-exist","errorCode":null,"errorMessage":"background music file does not exist","messagePattern":"background music file does not exist","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"app/services/bgm.py","lineNumber":328,"sourceCode":"    \"\"\"\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":310,"sourceCodeEnd":329,"githubUrl":"https://github.com/harry0703/MoneyPrinterTurbo/blob/1f9f19c2021a68d04df228f33e9099a0c947f6f8/app/services/bgm.py#L310-L329","documentation":"The default 'background music file does not exist' ValueError is the fallback raised by resolve_bgm_file when every candidate path failed against both whitelisted directories (uploaded_bgm_dir and utils.song_dir()). Each failure came from file_security.resolve_path_within_directory, so the actually raised message is the LAST error — typically 'file does not exist' or 'path is outside the allowed directory'. Relative paths are tried both as-is and joined with the project root, and the user upload directory wins over built-in songs on name collision.","triggerScenarios":"Passing a filename that exists in neither storage/bgm/ nor resource/songs/, or an absolute/relative path that escapes those directories (then the message becomes 'path is outside the allowed directory'). Both the raw candidate and the root-joined candidate must fail for this to fire.","commonSituations":"Storage volume not mounted (Docker rebuild lost storage/bgm), file deleted by cleanup while config still references it, absolute path from another machine, traversal attempts like '../../etc/passwd'.","solutions":["Confirm the file actually exists under storage/bgm/ (user uploads) or resource/songs/ (built-ins) on the machine running the app.","Re-upload the BGM or pick a currently listed track; update the saved task/config to reference an existing file.","If the path was absolute, switch to a bare filename so it resolves against the whitelisted directories."],"exampleFix":"// before\nresolve_bgm_file('/home/user/music/track.mp3')  # outside whitelists\n\n// after\nresolve_bgm_file('track.mp3')  # resolves within storage/bgm or resource/songs","handlingStrategy":"validation","validationCode":"import os\nfrom app.services.bgm import uploaded_bgm_dir\nfrom app.utils import utils\n\ndef bgm_exists(unsafe_name: str) -> bool:\n    for d in (uploaded_bgm_dir(create=False), utils.song_dir()):\n        if os.path.isfile(os.path.join(d, unsafe_name)):\n            return True\n    return False","typeGuard":null,"tryCatchPattern":"try:\n    resolved = resolve_bgm_file(path)\nexcept ValueError as e:\n    # 'file does not exist' or 'path is outside the allowed directory'\n    fallback_to_no_bgm(); warn_user(f'BGM unavailable: {e}')","preventionTips":["Persist bare filenames (not absolute paths) so resolution stays inside the whitelists.","Re-validate stored BGM references after storage migrations or Docker volume changes.","Run background-music without BGM (should_use_bgm gate) when resolution fails, instead of failing the whole video job."],"tags":["bgm","path-resolution","whitelist","file-not-found"],"backgroundTag":null,"analyzedSha":"1f9f19c2021a68d04df228f33e9099a0c947f6f8","analyzedAt":"2026-08-14T19:41:05.568Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}