AlistGo/alist · warning
cannot move to same parent directory
Error message
cannot move to same parent directory
What it means
executeMoveAPI refuses the operation up front: the source link's current ParentLinkID equals the requested destination ParentLinkID, so the move would be a no-op into the same folder. Note the link is fetched with srcLink, _ := d.getLink(ctx, linkID) — if that fetch errors, srcLink is nil and the check is silently skipped, deferring failure to the server.
Source
Thrown at drivers/proton_drive/util.go:690
func (d *ProtonDrive) executeMoveAPI(ctx context.Context, linkID string, req MoveRequest) error {
//fmt.Printf("DEBUG Move Request - Name: %s\n", req.Name)
//fmt.Printf("DEBUG Move Request - Hash: %s\n", req.Hash)
//fmt.Printf("DEBUG Move Request - OriginalHash: %s\n", req.OriginalHash)
//fmt.Printf("DEBUG Move Request - ParentLinkID: %s\n", req.ParentLinkID)
//fmt.Printf("DEBUG Move Request - Name length: %d\n", len(req.Name))
//fmt.Printf("DEBUG Move Request - NameSignatureEmail: %s\n", req.NameSignatureEmail)
//fmt.Printf("DEBUG Move Request - ContentHash: %v\n", req.ContentHash)
//fmt.Printf("DEBUG Move Request - NodePassphrase length: %d\n", len(req.NodePassphrase))
//fmt.Printf("DEBUG Move Request - NodePassphraseSignature length: %d\n", len(req.NodePassphraseSignature))
//fmt.Printf("DEBUG Move Request - SrcLinkID: %s\n", linkID)
//fmt.Printf("DEBUG Move Request - DstParentLinkID: %s\n", req.ParentLinkID)
//fmt.Printf("DEBUG Move Request - ShareID: %s\n", d.MainShare.ShareID)
srcLink, _ := d.getLink(ctx, linkID)
if srcLink != nil && srcLink.ParentLinkID == req.ParentLinkID {
return fmt.Errorf("cannot move to same parent directory")
}
moveURL := fmt.Sprintf(d.apiBase+"/drive/v2/volumes/%s/links/%s/move",
d.MainShare.VolumeID, linkID)
reqBody, err := json.Marshal(req)
if err != nil {
return fmt.Errorf("failed to marshal move request: %w", err)
}
httpReq, err := http.NewRequestWithContext(ctx, "PUT", moveURL, bytes.NewReader(reqBody))
if err != nil {
return fmt.Errorf("failed to create HTTP request: %w", err)
}
httpReq.Header.Set("Authorization", "Bearer "+d.credentials.AccessToken)
httpReq.Header.Set("Accept", d.protonJson)
httpReq.Header.Set("X-Pm-Appversion", d.webDriveAV)View on GitHub (pinned to 843d9dc814)
Solutions
- Treat as a no-op success in the caller: compare parent IDs before calling DirectMove and return the existing object
- In the driver, return a sentinel (e.g. ErrSameParent) or model.Obj nil-error so callers can distinguish no-op from failure
- Handle the getLink error instead of discarding it, so a stale link does not bypass the check
Example fix
// before
srcLink, _ := d.getLink(ctx, linkID)
if srcLink != nil && srcLink.ParentLinkID == req.ParentLinkID {
return fmt.Errorf("cannot move to same parent directory")
}
// after
srcLink, err := d.getLink(ctx, linkID)
if err != nil { return fmt.Errorf("failed to get link: %w", err) }
if srcLink.ParentLinkID == req.ParentLinkID {
return ErrSameParent // callers treat as no-op success
} Defensive patterns
Strategy: validation
Validate before calling
// before calling DirectMove, compare parents yourself:
srcLink, _ := d.getLink(ctx, srcID)
dstID := resolveDstParentID(dstDir)
if srcLink != nil && srcLink.ParentLinkID == dstID {
return srcObj, nil // no-op move, succeed silently
} Try / catch
if err := d.DirectMove(ctx, src, dst); err != nil {
if strings.Contains(err.Error(), "cannot move to same parent directory") {
return src, nil // treat as no-op success
}
} Prevention
- Guard drag-drop UIs from issuing moves to the same folder
- Handle the discarded getLink error in your fork so the check cannot be silently skipped
When it happens
Trigger: DirectMove called where dstDir is already the object's parent (common when a UI issues move on drop-to-same-folder, or path resolution of '/' maps to the same root); duplicate move retries after a partial success.
Common situations: Frontends that optimistically call move on every drag-drop; retry logic re-running an already-completed move; root-path handling where dstParentLinkID resolves to the current parent.
Related errors
- failed to find destination: %w
- cannot move in place
- missing source file id
- failed to get original hash: %w
- move operation failed with code: %d
AI-assisted analysis of AlistGo/alist@843d9dc814 (2026-08-15).
Data as JSON: /api/errors/f06446026efe689a.
Report an issue: GitHub.