{"record":{"id":"857d4948059f8567","repo":"AlistGo/alist","slug":"upload-part-failed-s","errorCode":null,"errorMessage":"upload part failed: %s","messagePattern":"upload part failed: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"drivers/doubao/util.go","lineNumber":711,"sourceCode":"\t\t\t\"Content-Disposition\": fmt.Sprintf(\"attachment; filename=%s\", url.QueryEscape(storeInfo.StoreURI)),\n\t\t})\n\n\t\treq.SetQueryParams(map[string]string{\n\t\t\t\"uploadid\":    uploadID,\n\t\t\t\"part_number\": strconv.FormatInt(partNumber, 10),\n\t\t\t\"phase\":       \"transfer\",\n\t\t})\n\n\t\treq.SetBody(data)\n\t\treq.SetContentLength(true)\n\t}, &uploadResp)\n\n\tif err != nil {\n\t\treturn resp, err\n\t}\n\n\tif uploadResp.Code != 2000 {\n\t\treturn resp, fmt.Errorf(\"upload part failed: %s\", uploadResp.Message)\n\t} else if uploadResp.Data.Crc32 != crc32Value {\n\t\treturn resp, fmt.Errorf(\"upload part failed: crc32 mismatch, expected %s, got %s\", crc32Value, uploadResp.Data.Crc32)\n\t}\n\n\treturn uploadResp.Data, nil\n}\n\n// 完成分片上传\nfunc (d *Doubao) completeMultipartUpload(config *UploadConfig, uploadUrl, uploadID string, parts []UploadPart) error {\n\tuploadResp := UploadResp{}\n\n\tstoreInfo := config.InnerUploadAddress.UploadNodes[0].StoreInfos[0]\n\n\tbody := _convertUploadParts(parts)\n\n\terr := utils.Retry(MaxRetryAttempts, time.Second, func() (err error) {\n\t\t_, err = d.uploadRequest(uploadUrl, http.MethodPost, storeInfo, func(req *resty.Request) {\n\t\t\treq.SetQueryParams(map[string]string{","sourceCodeStart":693,"sourceCodeEnd":729,"githubUrl":"https://github.com/AlistGo/alist/blob/843d9dc8149126976b2625911e45a4d3ffd6f2f5/drivers/doubao/util.go#L693-L729","documentation":"Returned by uploadPart when the server responded to a part 'phase=transfer' POST with a business code other than 2000. The part bytes were not (or not reliably) accepted; the message is the server's own explanation.","triggerScenarios":"Uploading a single chunk within _retryOperation where the part auth is stale, the part number/offset violates server expectations, body too large for the node, storage quota exceeded, or the server rejects the Content-Length handling (req.SetContentLength(true)) for this node.","commonSituations":"One flaky upload node among UploadNodes rejects parts intermittently, chunk size tuned larger than the node accepts, quota exhausted mid-upload, or session expiry during long multi-part uploads of large files.","solutions":["Retry the part (already done by _retryOperation; if it still fails, treat as persistent)","Check the server message for quota/auth specifics and address those","Reduce chunk size configuration so each part is comfortably under node limits","Re-init the upload session with a fresh token if the error indicates session expiry","Re-authenticate the driver if auth-related"],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"// part upload already runs under _retryOperation; on final failure fall back to smaller chunks\nif err := uploadAllParts(chunkSize); err != nil && strings.Contains(err.Error(), \"upload part failed\") {\n    return uploadAllParts(chunkSize / 2)\n}","preventionTips":["Keep part size below the node's documented maximum","Watch quota before starting large uploads","Re-init the session if part failures cluster after a long upload (token expiry)"],"tags":["doubao","upload","api-error","multipart","chunk","go"],"backgroundTag":null,"analyzedSha":"843d9dc8149126976b2625911e45a4d3ffd6f2f5","analyzedAt":"2026-08-15T12:14:11.722Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}