AlistGo/alist · error
move operation failed with code: %d
Error message
move operation failed with code: %d
What it means
Proton returned 200 for the move but the body's Code is not 1000. The numeric code carries the real reason: invalid/expired token, invalid hashes, target-parent not writable, or passphrase re-encryption rejected (bad NodePassphrase).
Source
Thrown at drivers/proton_drive/util.go:726
httpReq.Header.Set("X-Pm-Appversion", d.webDriveAV)
httpReq.Header.Set("X-Pm-Drive-Sdk-Version", d.sdkVersion)
httpReq.Header.Set("X-Pm-Uid", d.credentials.UID)
httpReq.Header.Set("Content-Type", "application/json")
client := &http.Client{}
resp, err := client.Do(httpReq)
if err != nil {
return fmt.Errorf("failed to execute move request: %w", err)
}
defer resp.Body.Close()
var moveResp RenameResponse
if err := json.NewDecoder(resp.Body).Decode(&moveResp); err != nil {
return fmt.Errorf("failed to decode move response: %w", err)
}
if moveResp.Code != 1000 {
return fmt.Errorf("move operation failed with code: %d", moveResp.Code)
}
return nil
}
func (d *ProtonDrive) DirectMove(ctx context.Context, srcObj model.Obj, dstDir model.Obj) (model.Obj, error) {
//fmt.Printf("DEBUG DirectMove: srcPath=%s, dstPath=%s", srcObj.GetPath(), dstDir.GetPath())
srcLink, err := d.searchByPath(ctx, srcObj.GetPath(), srcObj.IsDir())
if err != nil {
return nil, fmt.Errorf("failed to find source: %w", err)
}
var dstParentLinkID string
if dstDir.GetPath() == "/" {
dstParentLinkID = d.RootLink.LinkID
} else {
dstLink, err := d.searchByPath(ctx, dstDir.GetPath(), true)View on GitHub (pinned to 843d9dc814)
Solutions
- Log moveResp.Code and map known codes (auth vs hash vs permission) instead of showing only the number
- For hash errors, re-fetch the link, regenerate hashes and passphrase, retry once
- For permission codes, fail fast with a permission error
- Use the official proton-go move API which encodes these failure modes properly
Defensive patterns
Strategy: try-catch
Type guard
func isMoveCodeErr(err error) (code int, ok bool) {
var n int
if _, e := fmt.Sscanf(err.Error(), "move operation failed with code: %d", &n); e == nil { return n, true }
return 0, false
} Try / catch
if code, ok := isMoveCodeErr(err); ok {
if isAuthCode(code) { refreshCreds(); retry() }
if isPermissionCode(code) { return fmt.Errorf("no write access to destination") }
if isHashCode(code) { refetchLink(); regenerateHashesAndPassphrase(); retryOnce() }
} Prevention
- Verify write permission on destination share before moving
- Keep hashes and passphrase freshly computed from re-fetched links
- Map Proton error codes centrally in your integration
When it happens
Trigger: Moving into a share where the account lacks write permission; NodePassphrase re-encrypted with the wrong destination keyring; stale OriginalHash; name-hash collision (duplicate name) in the destination folder.
Common situations: Moves into folders shared read-only; cross-share moves where the destination parent keyring could not be derived; concurrent clients mutating the same tree; keyring/address-key drift after password reset (old keys revoked).
Related errors
AI-assisted analysis of AlistGo/alist@843d9dc814 (2026-08-15).
Data as JSON: /api/errors/050d13f8bf62f88d.
Report an issue: GitHub.