{"record":{"id":"ffcd43b683a54653","repo":"transloadit/uppy","slug":"c-error-prefix-failed-to-complete-multipart-uplo","errorCode":null,"errorMessage":"${C.ERROR_PREFIX}Failed to complete multipart upload: ${JSON.stringify(parsed)}","messagePattern":"(.+?)Failed to complete multipart upload: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/@uppy/aws-s3/src/s3-client/S3mini.ts","lineNumber":468,"sourceCode":"\n        if (!resultLocation || !resultKey) {\n          throw new Error(\n            `${C.ERROR_PREFIX}CompleteMultipartUpload response missing Location or Key: ${JSON.stringify(r)}`,\n          )\n        }\n\n        const etag = rawEtag ? U.sanitizeXmlETag(rawEtag) : undefined\n\n        return {\n          location: resultLocation,\n          bucket: resultBucket,\n          key: resultKey,\n          etag,\n        }\n      }\n    }\n\n    throw new Error(\n      `${C.ERROR_PREFIX}Failed to complete multipart upload: ${JSON.stringify(\n        parsed,\n      )}`,\n    )\n  }\n\n  /** Aborts a multipart upload and removes all uploaded parts. */\n  public override async abortMultipartUpload({\n    key,\n    uploadId,\n    signal,\n  }: IT.AbortMultipartUploadParams) {\n    this._checkKey(key)\n    if (!uploadId) {\n      throw new TypeError(C.ERROR_UPLOAD_ID_REQUIRED)\n    }\n\n    const { xhr } = await this.request({","sourceCodeStart":450,"sourceCodeEnd":486,"githubUrl":"https://github.com/transloadit/uppy/blob/5d4dedd02a1ac0ae022c75c54aca76558f88e256/packages/@uppy/aws-s3/src/s3-client/S3mini.ts#L450-L486","documentation":"completeMultipartUpload's fallback throw: the response was parsed but matched none of the expected success shapes (no Location/Key result, no recognizable error), so the client cannot determine the outcome of the completion request.","triggerScenarios":"S3 returns a 2xx with an empty or unexpected body for CompleteMultipartUpload; a non-S3-compatible server returns HTML/JSON instead of the expected XML.","commonSituations":"Using S3-compatible third-party storage (MinIO, R2, custom proxies) whose completion response differs; network middlewares truncating responses.","solutions":["Log the parsed payload to see what the endpoint actually returned","Retry the operation — the upload may or may not have completed; call listParts to check whether uploadId still exists (NoSuchUpload means it completed)","Verify S3 compatibility of the endpoint or upgrade @uppy/aws-s3 for endpoint-specific fixes"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"null","typeGuard":"null","tryCatchPattern":"try { await complete(...) } catch (e) { const exists = await listParts(...).then(() => true, () => false); if (!exists) return /* already completed */; throw e }","preventionTips":["Check uploadId existence via listParts to disambiguate outcome","Use standard S3-compatible endpoints","Retry with backoff on ambiguous completion failures"],"tags":["s3","multipart","unexpected-response"],"backgroundTag":"s3-multipart-complete-failed","analyzedSha":"5d4dedd02a1ac0ae022c75c54aca76558f88e256","analyzedAt":"2026-08-28T12:18:41.267Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}