{"record":{"id":"43e0d8fe3676a705","repo":"AlistGo/alist","slug":"string-data-43e0d8","errorCode":null,"errorMessage":"string(data)","messagePattern":"string\\(data\\)","errorType":"http","errorClass":null,"httpStatus":null,"severity":"error","filePath":"drivers/cloudreve_v4/util.go","lineNumber":374,"sourceCode":"\t\tres, err := base.HttpClient.Do(req)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\t// https://learn.microsoft.com/zh-cn/onedrive/developer/rest-api/api/driveitem_createuploadsession\n\t\tswitch {\n\t\tcase res.StatusCode >= 500 && res.StatusCode <= 504:\n\t\t\tretryCount++\n\t\t\tif retryCount > maxRetries {\n\t\t\t\tres.Body.Close()\n\t\t\t\treturn fmt.Errorf(\"upload failed after %d retries due to server errors, error %d\", maxRetries, res.StatusCode)\n\t\t\t}\n\t\t\tbackoff := time.Duration(1<<retryCount) * time.Second\n\t\t\tutils.Log.Warnf(\"[CloudreveV4-OneDrive] server errors %d while uploading, retrying after %v...\", res.StatusCode, backoff)\n\t\t\ttime.Sleep(backoff)\n\t\tcase res.StatusCode != 201 && res.StatusCode != 202 && res.StatusCode != 200:\n\t\t\tdata, _ := io.ReadAll(res.Body)\n\t\t\tres.Body.Close()\n\t\t\treturn errors.New(string(data))\n\t\tdefault:\n\t\t\tres.Body.Close()\n\t\t\tretryCount = 0\n\t\t\tfinish += byteSize\n\t\t\tup(float64(finish) * 100 / float64(file.GetSize()))\n\t\t}\n\t}\n\t// 上传成功发送回调请求\n\treturn d.request(http.MethodPost, \"/callback/onedrive/\"+u.SessionID+\"/\"+u.CallbackSecret, func(req *resty.Request) {\n\t\treq.SetBody(\"{}\")\n\t}, nil)\n}\n\nfunc (d *CloudreveV4) upS3(ctx context.Context, file model.FileStreamer, u FileUploadResp, up driver.UpdateProgress) error {\n\tvar finish int64 = 0\n\tvar chunk int = 0\n\tvar etags []string\n\tDEFAULT := int64(u.ChunkSize)","sourceCodeStart":356,"sourceCodeEnd":392,"githubUrl":"https://github.com/AlistGo/alist/blob/843d9dc8149126976b2625911e45a4d3ffd6f2f5/drivers/cloudreve_v4/util.go#L356-L392","documentation":"CloudreveV4 OneDrive-policy upload: a chunk response had a status outside {200, 201, 202} and the raw body is returned verbatim as the error. Like the V3 variant, the body is typically Microsoft Graph JSON or a proxy error page.","triggerScenarios":"upOneDrive chunk PUT returns e.g. 416 (range mismatch on resume), 404 (expired upload session URL), or 429 (throttle) — anything not 2xx and not 500-504 (those retry with backoff).","commonSituations":"Upload session URL expired (~15 min lifetime); resumed upload with wrong byte offset; Graph throttling under heavy parallelism; proxy stripping auth headers to Graph.","solutions":["Retry as a brand-new upload session.","Back off on 429s and lower upload concurrency/parallel chunk count.","Read the body — Graph error code/message states the exact problem.","Ensure no intermediary rewrites or caches PUT requests to the Graph upload URL."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":"func isGraphErrorBody(b string) bool { return strings.Contains(b, \"\\\"error\\\":{\\\"code\\\"\") }","tryCatchPattern":"if res.StatusCode != 200 && res.StatusCode != 201 && res.StatusCode != 202 {\n    data, _ := io.ReadAll(res.Body)\n    var g struct{ Error struct{ Code, Message string } }\n    if json.Unmarshal(data, &g) == nil && g.Error.Code != \"\" {\n        return fmt.Errorf(\"graph upload %s: %s\", g.Error.Code, g.Error.Message)\n    }\n    return errors.New(string(data))\n}","preventionTips":["Complete Graph upload sessions within their lifetime","Back off on 429 with Retry-After","Parse Graph JSON errors instead of surfacing raw bodies to users"],"tags":["cloudreve-v4","onedrive","upload","http-status","go"],"backgroundTag":null,"analyzedSha":"843d9dc8149126976b2625911e45a4d3ffd6f2f5","analyzedAt":"2026-08-15T12:14:11.722Z","schemaVersion":2},"datasetVersion":"2026-08-16T03:17:38.424Z"}