{"record":{"id":"3efae01812d62bff","repo":"AlistGo/alist","slug":"failed-to-re-encrypt-node-passphrase-w","errorCode":null,"errorMessage":"failed to re-encrypt node passphrase: %w","messagePattern":"failed to re-encrypt node passphrase: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"drivers/proton_drive/util.go","lineNumber":778,"sourceCode":"\tencryptedName, err := d.encryptFileName(ctx, srcObj.GetName(), dstParentLinkID)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to encrypt filename: %w\", err)\n\t}\n\n\tnewHash, err := d.generateNameHash(ctx, srcObj.GetName(), dstParentLinkID)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to generate new hash: %w\", err)\n\t}\n\n\toriginalHash, err := d.getOriginalNameHash(srcLink)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to get original hash: %w\", err)\n\t}\n\n\t// Re-encrypt node passphrase for new parent context\n\treencryptedPassphrase, err := d.reencryptNodePassphrase(ctx, srcLink, dstParentLinkID)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to re-encrypt node passphrase: %w\", err)\n\t}\n\n\tmoveReq := MoveRequest{\n\t\tParentLinkID:       dstParentLinkID,\n\t\tNodePassphrase:     reencryptedPassphrase,\n\t\tName:               encryptedName,\n\t\tNameSignatureEmail: d.MainShare.Creator,\n\t\tHash:               newHash,\n\t\tOriginalHash:       originalHash,\n\t\tContentHash:        nil,\n\n\t\t// *** Causes rejection ***\n\t\t/* NodePassphraseSignature: srcLink.NodePassphraseSignature, */\n\t}\n\n\t//fmt.Printf(\"DEBUG MoveRequest validation:\\n\")\n\t//fmt.Printf(\"  Name length: %d\\n\", len(moveReq.Name))\n\t//fmt.Printf(\"  Hash: %s\\n\", moveReq.Hash)","sourceCodeStart":760,"sourceCodeEnd":796,"githubUrl":"https://github.com/AlistGo/alist/blob/843d9dc8149126976b2625911e45a4d3ffd6f2f5/drivers/proton_drive/util.go#L760-L796","documentation":"DirectMove failed to re-encrypt the node's passphrase for the destination parent (reencryptNodePassphrase, util.go:815-847): it derives source-parent and destination-parent keyrings and re-wraps the link's NodePassphrase key packet. Failures are parent-link fetch errors, keyring derivation failures (shared folder / signature issues), or PGP errors in reencryptKeyPacket — undecryptable armored passphrase, wrong session-key packet, or encryption with the destination keyring failing.","triggerScenarios":"Moving between shares where either parent keyring cannot be derived; srcLink.NodePassphrase empty or not a valid armored PGP split message; account keys revoked after password reset so DecryptSessionKey fails; destination in a share not re-shared to this account's keys.","commonSituations":"Cross-share moves (personal -> shared or shared -> shared); mounts surviving a Proton password reset with stale keyrings; moving items whose passphrase was rotated by another client while cached.","solutions":["Check the wrapped error to localize: 'failed to get source/destination parent keyring' vs 'failed to re-encrypt key packet'","For keyring errors, re-initialize the driver (fresh address/share keys) and retry","Verify read+decrypt access on BOTH source parent and destination parent (list both folders)","If NodePassphrase is empty/invalid, re-fetch the source link with full metadata"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// pre-flight both parents must be listable (keyrings derivable)\nif _, err := d.List(ctx, srcParent); err != nil { return err }\nif _, err := d.List(ctx, dstDir); err != nil { return err }\nif srcLink.NodePassphrase == \"\" { return fmt.Errorf(\"source link lacks passphrase\") }","typeGuard":null,"tryCatchPattern":"if err := d.DirectMove(ctx, src, dst); err != nil {\n    if strings.Contains(err.Error(), \"failed to re-encrypt node passphrase\") {\n        // keyring access problem on source or destination parent:\n        // re-init driver (fresh address/share keys), verify share membership, retry once\n    }\n}","preventionTips":["Re-initialize the driver after Proton password resets so keyrings are fresh","Verify decrypt access on both source and destination parents before cross-share moves","Re-fetch the source link to guarantee a valid armored NodePassphrase"],"tags":["proton-drive","crypto","keyring","move","shared-folders"],"backgroundTag":null,"analyzedSha":"843d9dc8149126976b2625911e45a4d3ffd6f2f5","analyzedAt":"2026-08-15T12:14:11.722Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}