{"record":{"id":"62719b8cb28f50c4","repo":"yikart/AiToEarn","slug":"error-62719b","errorCode":null,"errorMessage":"上传封面失败,失败原因:合并分片失败","messagePattern":"上传封面失败,失败原因:合并分片失败","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"project/aitoearn-electron/electron/plat/shipinhao/index.ts","lineNumber":878,"sourceCode":"      const uploadCompleteRes = await this.uploadFile(\n        this.uploadCompleteUrl + `?UploadID=${uploadId}`,\n        Buffer.from(\n          JSON.stringify({\n            TransFlag: '0_0',\n            PartInfo: uploadPartInfo,\n          }),\n        ),\n        {\n          Authorization: uploadParams.authKey,\n          'Content-Type': 'application/json',\n          'X-Arguments': uploadArgumentsString,\n        },\n        undefined,\n        proxy,\n      );\n\n      if (!uploadCompleteRes.DownloadURL) {\n        throw new Error('上传封面失败,失败原因:合并分片失败');\n      }\n\n      return uploadCompleteRes.DownloadURL;\n    } catch (err: any) {\n      const errorMessage = err?.message || err || '未知';\n      throw new Error('上传封面失败,失败原因:' + errorMessage);\n    }\n  }\n\n  /**\n   * 提交官方剪辑任务\n   */\n  private async postClipUploadVideo(\n    traceKey: string,\n    startUploadTime: number,\n    endUploadTime: number,\n    remoteFileUrl: string,\n    fileInfo: any,","sourceCodeStart":860,"sourceCodeEnd":896,"githubUrl":"https://github.com/yikart/AiToEarn/blob/d3aa8bea5b146a8675607cf0144d891aad3e9683/project/aitoearn-electron/electron/plat/shipinhao/index.ts#L860-L896","documentation":"In uploadCoverFile, after all cover parts are uploaded, the complete/merge call must return a DownloadURL; if it does not, this error is thrown indicating the multipart merge failed server-side. The cover is not published and the video publish flow should abort or retry.","triggerScenarios":"uploadCoverFile → complete-upload response lacks DownloadURL: part integrity check failure, missing parts, expired upload session before complete, or COS returning an error body.","commonSituations":"Interrupted part upload (network/proxy drop) making the merge invalid, stale UploadID after long delays, or COS rejecting due to InvalidPart/NoSuchUpload.","solutions":["Retry the whole cover upload with freshly obtained upload params.","Confirm each part upload returned an ETag before invoking the complete call.","Inspect uploadCompleteRes for a COS error code and address it (e.g. re-sign, reduce delay).","Check proxy/network stability during the cover upload sequence."],"exampleFix":"null","handlingStrategy":"retry","validationCode":"// ensure all parts succeeded before complete\nif (!lastPartRes?.ETag) throw new Error('last cover part missing ETag');","typeGuard":"function hasDownloadUrl(res: unknown): res is { DownloadURL: string } {\n  return typeof (res as any)?.DownloadURL === 'string' && (res as any).DownloadURL.length > 0;\n}","tryCatchPattern":"try {\n  const coverUrl = await service.uploadCoverFile(/*...*/);\n} catch (e) {\n  if (e.message.includes('合并分片失败')) {\n    // restart cover upload with fresh upload params\n  }\n}","preventionTips":["Verify each part upload returned an ETag before the complete call","Complete the merge soon after part uploads to avoid UploadID expiry","Keep network/proxy stable across the whole cover upload","Retry the full cover upload on merge failure"],"tags":["upload","cover","shipinhao","multipart","cos"],"backgroundTag":"multipart-upload-complete-failed","analyzedSha":"d3aa8bea5b146a8675607cf0144d891aad3e9683","analyzedAt":"2026-08-31T14:19:24.185Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}