{"record":{"id":"8c240e8c3ad8ad76","repo":"AlistGo/alist","slug":"rename-failed-with-status-d","errorCode":null,"errorMessage":"rename failed with status %d","messagePattern":"rename failed with status (.+?)","errorType":"http","errorClass":null,"httpStatus":null,"severity":"error","filePath":"drivers/proton_drive/util.go","lineNumber":657,"sourceCode":"\t\treturn fmt.Errorf(\"failed to create HTTP request: %w\", err)\n\t}\n\n\thttpReq.Header.Set(\"Content-Type\", \"application/json\")\n\thttpReq.Header.Set(\"Accept\", d.protonJson)\n\thttpReq.Header.Set(\"X-Pm-Appversion\", d.webDriveAV)\n\thttpReq.Header.Set(\"X-Pm-Drive-Sdk-Version\", d.sdkVersion)\n\thttpReq.Header.Set(\"X-Pm-Uid\", d.credentials.UID)\n\thttpReq.Header.Set(\"Authorization\", \"Bearer \"+d.credentials.AccessToken)\n\n\tclient := &http.Client{}\n\tresp, err := client.Do(httpReq)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to execute rename request: %w\", err)\n\t}\n\tdefer resp.Body.Close()\n\n\tif resp.StatusCode != http.StatusOK {\n\t\treturn fmt.Errorf(\"rename failed with status %d\", resp.StatusCode)\n\t}\n\n\tvar renameResp RenameResponse\n\tif err := json.NewDecoder(resp.Body).Decode(&renameResp); err != nil {\n\t\treturn fmt.Errorf(\"failed to decode rename response: %w\", err)\n\t}\n\n\tif renameResp.Code != 1000 {\n\t\treturn fmt.Errorf(\"rename failed with code %d\", renameResp.Code)\n\t}\n\n\treturn nil\n}\n\nfunc (d *ProtonDrive) executeMoveAPI(ctx context.Context, linkID string, req MoveRequest) error {\n\t//fmt.Printf(\"DEBUG Move Request - Name: %s\\n\", req.Name)\n\t//fmt.Printf(\"DEBUG Move Request - Hash: %s\\n\", req.Hash)\n\t//fmt.Printf(\"DEBUG Move Request - OriginalHash: %s\\n\", req.OriginalHash)","sourceCodeStart":639,"sourceCodeEnd":675,"githubUrl":"https://github.com/AlistGo/alist/blob/843d9dc8149126976b2625911e45a4d3ffd6f2f5/drivers/proton_drive/util.go#L639-L675","documentation":"The rename endpoint answered with a non-200 HTTP status. The response body — which contains Proton's specific error code and message — is discarded, so the numeric status is all you get. 401 (expired token) and 429 (rate limit) are the dominant causes because this raw path never refreshes credentials.","triggerScenarios":"Expired AccessToken after long uptime (401); too many renames in a burst (429 with Retry-After); insufficient permission on a shared item (403); API route changed after a Proton backend update (404/410).","commonSituations":"Mounts running for days on one token; bulk rename scripts; renaming inside a share where the account only has viewer rights; Proton API version bumps breaking the hardcoded /drive/v2 path.","solutions":["Read and include resp.Body in the error so the real API code is visible","On 401, refresh credentials (re-auth or use the official client's session) then retry","On 429, honor Retry-After and back off","On 403, verify the account has edit rights on the containing share"],"exampleFix":"// before\nif resp.StatusCode != http.StatusOK {\n\treturn fmt.Errorf(\"rename failed with status %d\", resp.StatusCode)\n}\n// after\nif resp.StatusCode != http.StatusOK {\n\tbody, _ := io.ReadAll(io.LimitReader(resp.Body, 4096))\n\treturn fmt.Errorf(\"rename failed with status %d: %s\", resp.StatusCode, body)\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":"func isRenameStatusErr(err error) (code int, ok bool) {\n    var n int\n    if _, e := fmt.Sscanf(err.Error(), \"rename failed with status %d\", &n); e == nil { return n, true }\n    return 0, false\n}","tryCatchPattern":"if code, ok := isRenameStatusErr(err); ok {\n    switch code {\n    case 401: refreshCreds(); retry()\n    case 429: sleep(retryAfter); retry()\n    case 403: return fmt.Errorf(\"no edit permission\")\n    default: return err\n    }\n}","preventionTips":["Refresh access tokens proactively before expiry on long-lived mounts","Patch the driver to include the response body in status errors so diagnosis is possible"],"tags":["proton-drive","http","auth","rate-limit"],"backgroundTag":null,"analyzedSha":"843d9dc8149126976b2625911e45a4d3ffd6f2f5","analyzedAt":"2026-08-15T12:14:11.722Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}