hcengineering/platform · error · DatalakeError
Failed to complete multipart upload
Error message
Failed to complete multipart upload
What it means
DatalakeError thrown when the final POST to /upload/multipart/{workspace}/{object}/complete fails, so the uploaded parts are not assembled into the final object. fetchSafe errors (network failure or non-OK responses such as 404 unknown uploadId, 400 invalid part list) are caught and rethrown as this single error; the real cause is logged via ctx.error.
Source
Thrown at foundations/server/packages/datalake/src/client.ts:460
parts: MultipartUploadPart[]
): Promise<ObjectMetadata> {
const path = `/upload/multipart/${workspace}/${encodeURIComponent(objectName)}/complete`
const url = new URL(concatLink(this.endpoint, path))
url.searchParams.set('uploadId', multipart.uploadId)
try {
const res = await fetchSafe(ctx, url, {
method: 'POST',
body: JSON.stringify({ parts }),
headers: {
'Content-Type': 'application/json',
...this.headers
}
})
return (await res.json()) as ObjectMetadata
} catch (err: any) {
ctx.error('failed to complete multipart upload', { workspace, objectName, err })
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')View on GitHub (pinned to 63e28dc964)
Solutions
- Read the wrapped err in ctx.error logs to identify the server response text.
- Retry the full uploadWithMultipart from scratch (fresh uploadId).
- Ensure all parts uploaded successfully before complete; reduce upload duration to avoid session expiry.
- Check datalake server logs for the complete-request failure.
Example fix
// before
await client.uploadWithMultipart(ctx, ws, name, data)
// after
try {
await client.uploadWithMultipart(ctx, ws, name, data)
} catch (err) {
if (err instanceof DatalakeError) {
console.error('upload completion failed, restarting upload')
await client.uploadWithMultipart(ctx, ws, name, data)
} else throw err
} Defensive patterns
Strategy: retry
Try / catch
try {
await client.uploadWithMultipart(ctx, ws, name, data)
} catch (err) {
if (err instanceof DatalakeError) {
// restart with a fresh uploadId
await client.uploadWithMultipart(ctx, ws, name, data)
} else throw err
} Prevention
- Complete uploads promptly to avoid server-side session expiry.
- Verify all parts succeeded before calling complete.
- Keep client and datalake server versions compatible.
- Retry the whole upload, not just the complete step.
When it happens
Trigger: uploadWithMultipart reaches the complete step and fetchSafe throws: network failure, expired/aborted uploadId, missing or malformed parts payload, or server 5xx.
Common situations: Long-running uploads where the server-side multipart session times out before complete is called; an earlier part upload failed silently; client/server version mismatch rejecting the parts JSON.
Related errors
- Failed to upload multipart part
- response.statusText
- Failed to fetch config
- unknownError(response.statusText)
- Failed to delete file
AI-assisted analysis of hcengineering/platform@63e28dc964 (2026-08-29).
Data as JSON: /api/errors/3f0a57ed769ed5f5.
Report an issue: GitHub.