{"record":{"id":"10939a64d3c47338","repo":"AlistGo/alist","slug":"rename-failed-with-code-d","errorCode":null,"errorMessage":"rename failed with code %d","messagePattern":"rename failed with code (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"drivers/proton_drive/util.go","lineNumber":666,"sourceCode":"\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)\n\t//fmt.Printf(\"DEBUG Move Request - ParentLinkID: %s\\n\", req.ParentLinkID)\n\n\t//fmt.Printf(\"DEBUG Move Request - Name length: %d\\n\", len(req.Name))\n\t//fmt.Printf(\"DEBUG Move Request - NameSignatureEmail: %s\\n\", req.NameSignatureEmail)\n\t//fmt.Printf(\"DEBUG Move Request - ContentHash: %v\\n\", req.ContentHash)\n\t//fmt.Printf(\"DEBUG Move Request - NodePassphrase length: %d\\n\", len(req.NodePassphrase))\n\t//fmt.Printf(\"DEBUG Move Request - NodePassphraseSignature length: %d\\n\", len(req.NodePassphraseSignature))\n\n\t//fmt.Printf(\"DEBUG Move Request - SrcLinkID: %s\\n\", linkID)","sourceCodeStart":648,"sourceCodeEnd":684,"githubUrl":"https://github.com/AlistGo/alist/blob/843d9dc8149126976b2625911e45a4d3ffd6f2f5/drivers/proton_drive/util.go#L648-L684","documentation":"Proton answered 200 but the JSON body's Code field is not 1000 (the success code). This is the API-level rejection of the rename: common Proton codes include 401-equivalents (invalid token), 2029/2028-style hash mismatches (Hash or OriginalHash wrong), and duplicate-name conflicts in the target folder.","triggerScenarios":"OriginalHash stale because the file was renamed by another client since the link was fetched; newHash computed with the wrong parent hash key; Name already exists in the parent (Proton enforces per-folder name-hash uniqueness); access token rejected at the API layer.","commonSituations":"Two clients renaming the same file concurrently; rename after the mount's link cache went stale; keyring/address-key problems producing a wrong name hash; shared-folder permission edges.","solutions":["Re-fetch the link (fresh OriginalHash) and recompute both hashes, then retry once","If the code indicates a name conflict, auto-suffix or surface a 'name exists' error to the user","Map and log the numeric code so 401 vs hash-mismatch vs conflict is distinguishable","Move renames onto the official proton-go API client which decodes these codes for you"],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":"func isRenameCodeErr(err error) (code int, ok bool) {\n    var n int\n    if _, e := fmt.Sscanf(err.Error(), \"rename failed with code %d\", &n); e == nil { return n, true }\n    return 0, false\n}","tryCatchPattern":"if code, ok := isRenameCodeErr(err); ok {\n    if isAuthCode(code) { refreshCreds(); retry() }\n    else if isHashMismatchCode(code) { refetchLink(); recomputeHashes(); retryOnce() }\n    else if isNameConflictCode(code) { newName = uniquify(newName); retry() }\n}","preventionTips":["Re-fetch link metadata immediately before renaming to keep OriginalHash fresh","Avoid two clients renaming the same tree concurrently","Map Proton API codes in one place so handling stays maintainable"],"tags":["proton-drive","rename","api","hash"],"backgroundTag":null,"analyzedSha":"843d9dc8149126976b2625911e45a4d3ffd6f2f5","analyzedAt":"2026-08-15T12:14:11.722Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}