transloadit/uppy · error · Error

${C.ERROR_PREFIX}Failed to abort multipart upload: ${String(

Error message

${C.ERROR_PREFIX}Failed to abort multipart upload: ${String(parsed.error.message)}

What it means

abortMultipartUpload sent a DELETE but the response body parsed to an S3-style <Error> payload with a message, meaning S3 refused the abort (e.g. the upload no longer exists).

Source

Thrown at packages/@uppy/aws-s3/src/s3-client/S3mini.ts:499

    this._checkKey(key)
    if (!uploadId) {
      throw new TypeError(C.ERROR_UPLOAD_ID_REQUIRED)
    }

    const { xhr } = await this.request({
      request: { method: 'DELETE', key, uploadId },
      signal,
    })

    const parsed = U.parseXml(xhr.responseText) as Record<string, unknown>
    if (
      parsed &&
      'error' in parsed &&
      typeof parsed.error === 'object' &&
      parsed.error !== null &&
      'message' in parsed.error
    ) {
      throw new Error(
        `${C.ERROR_PREFIX}Failed to abort multipart upload: ${String(
          parsed.error.message,
        )}`,
      )
    }
  }

  private _buildCompleteMultipartUploadXml(
    parts: Array<IT.UploadPart>,
  ): string {
    let xml = '<CompleteMultipartUpload>'
    for (const part of parts) {
      xml += `<Part><PartNumber>${part.partNumber}</PartNumber><ETag>${part.etag}</ETag></Part>`
    }
    xml += '</CompleteMultipartUpload>'
    return xml
  }

View on GitHub (pinned to 5d4dedd02a)

Solutions

  1. If the parsed error is NoSuchUpload, treat the abort as already done and ignore it
  2. Ensure abort is only called once per upload (idempotent wrapper)
  3. Check that the same key and uploadId from creation are used

Example fix

// before
await s3Mini.abortMultipartUpload({ key, uploadId })

// after
try {
  await s3Mini.abortMultipartUpload({ key, uploadId })
} catch (err) {
  if (!String(err.message).includes('NoSuchUpload')) throw err
}
Defensive patterns

Strategy: fallback

Validate before calling

null

Type guard

null

Try / catch

try { await abort(...) } catch (e) { if (String(e?.message).includes('NoSuchUpload')) return; throw e }

Prevention

When it happens

Trigger: Aborting an uploadId that was already completed or aborted (NoSuchUpload), or aborting a key/uploadId pair that never existed.

Common situations: Double abort attempts, retry logic aborting after a successful complete, stale persisted state after server restarts.

Related errors


AI-assisted analysis of transloadit/uppy@5d4dedd02a (2026-08-28). Data as JSON: /api/errors/b47c3b312cae5c65. Report an issue: GitHub.