diff --git a/src/azul/service/storage_service.py b/src/azul/service/storage_service.py index 47e0366c66..8321809cec 100644 --- a/src/azul/service/storage_service.py +++ b/src/azul/service/storage_service.py @@ -273,6 +273,12 @@ def complete_multipart_upload(self, etags: Sequence[str], overwrite: bool = True, ) -> None: + if len(etags) == 0: + # S3 requires at least one part, even for empty files + etags = [self.upload_multipart_part(object_key=object_key, + upload_id=upload_id, + part_number=1, + buffer=b'')] parts: list[CompletedPartTypeDef] = [ { 'PartNumber': index + 1, diff --git a/test/service/test_manifest.py b/test/service/test_manifest.py index 7f81b5f1c7..160a08ada3 100644 --- a/test/service/test_manifest.py +++ b/test/service/test_manifest.py @@ -989,6 +989,12 @@ def test_verbatim_jsonl_manifest(self): expected = self._load_canned_manifest(*path) self._assert_jsonl(expected, response) + def test_verbatim_jsonl_manifest_empty(self): + filters = {'projectId': {'is': ['00000000-0000-0000-0000-000000000000']}} + response = self._get_manifest(ManifestFormat.verbatim_jsonl, filters) + self.assertEqual(200, response.status_code) + self._assert_jsonl([], response) + def test_verbatim_pfb_manifest(self): response = self._get_manifest(ManifestFormat.verbatim_pfb, filters={}) self.assertEqual(200, response.status_code)