{"record":{"id":"5331eb91bf5cf7cd","repo":"AlistGo/alist","slug":"wukong-init-multipart-upload-returns-empty-uploadi","errorCode":null,"errorMessage":"wukong init multipart upload returns empty uploadid","messagePattern":"wukong init multipart upload returns empty uploadid","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"drivers/wukong/driver.go","lineNumber":661,"sourceCode":"\t\tSetHeader(\"Authorization\", auth).\n\t\tSetQueryParams(map[string]string{\n\t\t\t\"uploadmode\": \"part\",\n\t\t\t\"phase\":      \"init\",\n\t\t}).\n\t\tSetResult(&resp)\n\tif storageUser != \"\" {\n\t\treq.SetHeader(\"X-Storage-U\", storageUser)\n\t}\n\tuploadURL := fmt.Sprintf(\"https://%s/upload/v1/%s\", host, storeURI)\n\t_, err := req.Post(uploadURL)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\tif resp.Code != minUploadSubmitSuccess {\n\t\treturn \"\", fmt.Errorf(\"wukong init multipart upload failed: code=%d message=%s\", resp.Code, resp.Message)\n\t}\n\tif resp.Data.UploadID == \"\" {\n\t\treturn \"\", errors.New(\"wukong init multipart upload returns empty uploadid\")\n\t}\n\treturn resp.Data.UploadID, nil\n}\n\nfunc (d *Wukong) uploadMultipartPart(ctx context.Context, host, storeURI, auth, storageUser, uploadID string, partNumber int, data []byte, crc32Hex string) (string, error) {\n\tvar resp tosUploadResp\n\treq := base.NewRestyClient().R().\n\t\tSetContext(ctx).\n\t\tSetHeader(\"Host\", host).\n\t\tSetHeader(\"Referer\", webReferer).\n\t\tSetHeader(\"Origin\", \"https://pan.wkbrowser.com\").\n\t\tSetHeader(\"Authorization\", auth).\n\t\tSetHeader(\"Content-Type\", \"application/octet-stream\").\n\t\tSetHeader(\"Content-Crc32\", crc32Hex).\n\t\tSetHeader(\"Content-Length\", strconv.Itoa(len(data))).\n\t\tSetQueryParams(map[string]string{\n\t\t\t\"uploadid\":    uploadID,\n\t\t\t\"part_number\": strconv.Itoa(partNumber),","sourceCodeStart":643,"sourceCodeEnd":679,"githubUrl":"https://github.com/AlistGo/alist/blob/843d9dc8149126976b2625911e45a4d3ffd6f2f5/drivers/wukong/driver.go#L643-L679","documentation":"Thrown when the TOS (ByteDance object storage) init-multipart-upload endpoint returns the success code (minUploadSubmitSuccess) but an empty Data.UploadID. The uploadID is required by every subsequent UploadPart and CompleteMultipartUpload call; without it the multipart session cannot proceed, so the driver aborts rather than sending parts against a nonexistent session.","triggerScenarios":"POST https://{host}/upload/v1/{storeURI} answers code==success yet UploadID is \"\" — backend session-provisioning glitch, an expired/rejected StoreURI/Auth from an older apply response, or a schema change moving the upload id to a different field.","commonSituations":"Long pause between applyUploadInner and the actual upload so the store credentials went stale; TOS regional hiccups; driver version drift with the storage API.","solutions":["Restart the upload from scratch (new apply + new StoreURI/Auth) — stale store credentials are the most common cause","Retry after a delay if the backend is having a transient issue","Update the wukong driver in case the TOS response schema changed"],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"if err != nil && strings.Contains(err.Error(), \"empty uploadid\") {\n    // store credentials may be stale: restart apply + init, not just init\n    return d.Put(ctx, dstDir, file, up)\n}","preventionTips":["Minimize delay between applyUploadInner and the actual multipart upload","On any multipart failure, restart the entire upload flow for fresh StoreURI/Auth","Update driver for TOS response schema changes"],"tags":["wukong","driver","upload","multipart","tos","server-side"],"backgroundTag":null,"analyzedSha":"843d9dc8149126976b2625911e45a4d3ffd6f2f5","analyzedAt":"2026-08-15T12:14:11.722Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}