{"record":{"id":"3f0a57ed769ed5f5","repo":"hcengineering/platform","slug":"failed-to-complete-multipart-upload-3f0a57","errorCode":null,"errorMessage":"Failed to complete multipart upload","messagePattern":"Failed to complete multipart upload","errorType":"exception","errorClass":"DatalakeError","httpStatus":null,"severity":"error","filePath":"foundations/server/packages/datalake/src/client.ts","lineNumber":460,"sourceCode":"    parts: MultipartUploadPart[]\n  ): Promise<ObjectMetadata> {\n    const path = `/upload/multipart/${workspace}/${encodeURIComponent(objectName)}/complete`\n    const url = new URL(concatLink(this.endpoint, path))\n    url.searchParams.set('uploadId', multipart.uploadId)\n\n    try {\n      const res = await fetchSafe(ctx, url, {\n        method: 'POST',\n        body: JSON.stringify({ parts }),\n        headers: {\n          'Content-Type': 'application/json',\n          ...this.headers\n        }\n      })\n      return (await res.json()) as ObjectMetadata\n    } catch (err: any) {\n      ctx.error('failed to complete multipart upload', { workspace, objectName, err })\n      throw new DatalakeError('Failed to complete multipart upload')\n    }\n  }\n\n  private async multipartUploadAbort (\n    ctx: MeasureContext,\n    workspace: WorkspaceUuid,\n    objectName: string,\n    multipart: MultipartUpload\n  ): Promise<void> {\n    const path = `/upload/multipart/${workspace}/${encodeURIComponent(objectName)}/abort`\n    const url = new URL(concatLink(this.endpoint, path))\n    url.searchParams.set('uploadId', multipart.uploadId)\n\n    try {\n      await fetchSafe(ctx, url, { method: 'POST', headers: { ...this.headers } })\n    } catch (err: any) {\n      ctx.error('failed to abort multipart upload', { workspace, objectName, err })\n      throw new DatalakeError('Failed to abort multipart upload')","sourceCodeStart":442,"sourceCodeEnd":478,"githubUrl":"https://github.com/hcengineering/platform/blob/63e28dc96483967b2fc21c881b3f1023c1de7718/foundations/server/packages/datalake/src/client.ts#L442-L478","documentation":"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.","triggerScenarios":"uploadWithMultipart reaches the complete step and fetchSafe throws: network failure, expired/aborted uploadId, missing or malformed parts payload, or server 5xx.","commonSituations":"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.","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."],"exampleFix":"// before\nawait client.uploadWithMultipart(ctx, ws, name, data)\n// after\ntry {\n  await client.uploadWithMultipart(ctx, ws, name, data)\n} catch (err) {\n  if (err instanceof DatalakeError) {\n    console.error('upload completion failed, restarting upload')\n    await client.uploadWithMultipart(ctx, ws, name, data)\n  } else throw err\n}","handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  await client.uploadWithMultipart(ctx, ws, name, data)\n} catch (err) {\n  if (err instanceof DatalakeError) {\n    // restart with a fresh uploadId\n    await client.uploadWithMultipart(ctx, ws, name, data)\n  } else throw err\n}","preventionTips":["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."],"tags":["multipart-upload","http","network"],"backgroundTag":"multipart-upload-failed","analyzedSha":"63e28dc96483967b2fc21c881b3f1023c1de7718","analyzedAt":"2026-08-29T15:21:27.377Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}