hcengineering/platform · warning · DatalakeError

Failed to abort multipart upload

Error message

Failed to abort multipart upload

What it means

DatalakeError thrown when the POST to /upload/multipart/{workspace}/{object}/abort fails. Abort is the cleanup path used by uploadWithMultipart's catch block, so this error usually appears while another upload error is already propagating and indicates the server could not release the multipart session.

Source

Thrown at foundations/server/packages/datalake/src/client.ts:478

      throw new DatalakeError('Failed to complete multipart upload')
    }
  }

  private async multipartUploadAbort (
    ctx: MeasureContext,
    workspace: WorkspaceUuid,
    objectName: string,
    multipart: MultipartUpload
  ): Promise<void> {
    const path = `/upload/multipart/${workspace}/${encodeURIComponent(objectName)}/abort`
    const url = new URL(concatLink(this.endpoint, path))
    url.searchParams.set('uploadId', multipart.uploadId)

    try {
      await fetchSafe(ctx, url, { method: 'POST', headers: { ...this.headers } })
    } catch (err: any) {
      ctx.error('failed to abort multipart upload', { workspace, objectName, err })
      throw new DatalakeError('Failed to abort multipart upload')
    }
  }
}

async function toBuffer (data: Buffer | string | Readable): Promise<Buffer> {
  if (Buffer.isBuffer(data)) {
    return data
  } else if (typeof data === 'string') {
    return Buffer.from(data)
  } else if (data instanceof Readable) {
    const chunks: Buffer[] = []
    for await (const chunk of data) {
      chunks.push(chunk)
    }
    return Buffer.concat(chunks as any)
  } else {
    throw new TypeError('Unsupported data type')
  }

View on GitHub (pinned to 63e28dc964)

Solutions

  1. Treat as secondary: inspect the original upload error first (it precedes this one).
  2. Log and continue - a 404 usually means the session is already gone and no cleanup is needed.
  3. Verify the datalake service is reachable; orphaned sessions are typically garbage-collected server-side.
  4. Check server logs for the abort request if sessions leak.

Example fix

// before
try {
  await upload()
} catch (err) {
  await client.abort(ctx, ws, name)
}
// after
try {
  await upload()
} catch (err) {
  try {
    await client.abort(ctx, ws, name)
  } catch (abortErr) {
    console.warn('abort failed, session may already be gone', abortErr)
  }
  throw err
}
Defensive patterns

Strategy: try-catch

Try / catch

try {
  await client.abort(ctx, ws, name)
} catch (abortErr) {
  // cleanup failure is non-fatal; the original error matters more
  console.warn('multipart abort failed', abortErr)
}

Prevention

When it happens

Trigger: uploadWithMultipart fails and calls multipartUploadAbort, but fetchSafe throws: network failure, 404 for an expired/never-created uploadId, or a server error on the abort endpoint.

Common situations: UploadId already expired or completed server-side; datalake service unreachable during error cleanup; stale session after a service restart.

Related errors


AI-assisted analysis of hcengineering/platform@63e28dc964 (2026-08-29). Data as JSON: /api/errors/91b4c2762e9d151d. Report an issue: GitHub.