{"record":{"id":"0d9bb57297242b54","repo":"harry0703/MoneyPrinterTurbo","slug":"background-music-file-is-empty","errorCode":null,"errorMessage":"background music file is empty","messagePattern":"background music file is empty","errorType":"validation","errorClass":"BgmUploadError","httpStatus":400,"severity":"error","filePath":"app/services/bgm.py","lineNumber":213,"sourceCode":"            suffix=Path(safe_name).suffix.lower(),\n            dir=target_dir,\n        )\n        with os.fdopen(descriptor, \"wb\") as output:\n            while True:\n                chunk = source.read(_COPY_CHUNK_BYTES)\n                if not chunk:\n                    break\n                if not isinstance(chunk, (bytes, bytearray, memoryview)):\n                    raise BgmUploadError(\"background music upload must be binary\")\n                total_bytes += len(chunk)\n                if total_bytes > MAX_BGM_UPLOAD_BYTES:\n                    raise BgmUploadError(\"background music file exceeds the 30 MB limit\")\n                output.write(chunk)\n            output.flush()\n            os.fsync(output.fileno())\n\n        if total_bytes == 0:\n            raise BgmUploadError(\"background music file is empty\")\n        return safe_name, temp_path, total_bytes\n    except Exception as exc:\n        _remove_staged_file(temp_path)\n        if isinstance(exc, BgmUploadError):\n            raise\n        if isinstance(exc, OSError):\n            raise BgmServiceError(\"failed to stage background music upload\") from exc\n        raise\n    finally:\n        # Streamlit 还需要使用同一个 UploadedFile 做浏览器试听；恢复文件指针可\n        # 避免校验后播放器或最终保存读取到空内容。\n        try:\n            source.seek(0)\n        except (AttributeError, OSError):\n            pass\n\n\ndef validate_bgm_upload(filename: str, source: BinaryIO) -> str:","sourceCodeStart":195,"sourceCodeEnd":231,"githubUrl":"https://github.com/harry0703/MoneyPrinterTurbo/blob/1f9f19c2021a68d04df228f33e9099a0c947f6f8/app/services/bgm.py#L195-L231","documentation":"Raised after the copy loop in stage_bgm_upload when total_bytes == 0, i.e. the uploaded source produced an EOF on the very first read. The temp file was created and fsynced but no content was written, so it is removed and BgmUploadError('background music file is empty') is raised. This rejects zero-byte uploads before FFmpeg validation ever runs.","triggerScenarios":"Submitting an empty (0-byte) file to the BGM upload endpoint, or a file-like object already at EOF because a previous validation pass consumed it without seeking back to 0.","commonSituations":"Front-end bug sending an empty FormData part; the same UploadedFile read twice without seek(0) — note stage_bgm_upload itself restores the pointer in finally, but other code that reads first may not; truncated uploads from flaky networks.","solutions":["Check the file size before calling the API (seek to end / os.fstat) and reject or skip empty files client-side.","If the file object was previously read, call source.seek(0) before staging.","Verify the upload is not a placeholder/dummy file created by the frontend on failure."],"exampleFix":"// before\nsource.seek(0)  # missing -> EOF immediately\nsafe_name, temp_path, size = stage_bgm_upload(source, name)\n\n// after\nsource.seek(0)\nif isinstance(source, (io.RawIOBase, io.BufferedIOBase)) and not source.read(1):\n    raise ValueError('empty upload')\nsource.seek(0)\nsafe_name, temp_path, size = stage_bgm_upload(source, name)","handlingStrategy":"validation","validationCode":"fh.seek(0, os.SEEK_END)\nsize = fh.tell()\nfh.seek(0)\nif size == 0:\n    raise ClientError('empty file')","typeGuard":null,"tryCatchPattern":"try:\n    stage_bgm_upload(fh, filename)\nexcept BgmUploadError as e:\n    if 'is empty' in str(e):\n        show_user('The selected file is empty; re-export the audio')","preventionTips":["seek(0) any file object that was previously read before handing it to staging.","Reject 0-byte files at the form/upload boundary.","Remember staging restores the pointer in finally, but other readers may not — always reset before reuse."],"tags":["bgm","upload","empty-file","validation"],"backgroundTag":null,"analyzedSha":"1f9f19c2021a68d04df228f33e9099a0c947f6f8","analyzedAt":"2026-08-14T19:41:05.568Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}