AlistGo/alist · error
same-name files cannot be moved
Error message
same-name files cannot be moved
What it means
Returned by Alias.Move when getReqPath for the source object fails with errs.NotImplement: with ProtectSameName enabled, the source path exists in multiple underlying destinations sharing one alias key, so the driver cannot determine which physical file to move.
Source
Thrown at drivers/alias/driver.go:150
return errs.PermissionDenied
}
reqPath, err := d.getReqPath(ctx, parentDir, true)
if err == nil {
return fs.MakeDir(ctx, stdpath.Join(*reqPath, dirName))
}
if errs.IsNotImplement(err) {
return errors.New("same-name dirs cannot make sub-dir")
}
return err
}
func (d *Alias) Move(ctx context.Context, srcObj, dstDir model.Obj) error {
if !d.Writable {
return errs.PermissionDenied
}
srcPath, err := d.getReqPath(ctx, srcObj, false)
if errs.IsNotImplement(err) {
return errors.New("same-name files cannot be moved")
}
if err != nil {
return err
}
dstPath, err := d.getReqPath(ctx, dstDir, true)
if errs.IsNotImplement(err) {
return errors.New("same-name dirs cannot be moved to")
}
if err != nil {
return err
}
return fs.Move(ctx, *srcPath, *dstPath)
}
func (d *Alias) Rename(ctx context.Context, srcObj model.Obj, newName string) error {
if !d.Writable {
return errs.PermissionDenied
}View on GitHub (pinned to 843d9dc814)
Solutions
- Use unique alias keys per destination instead of one key over many paths
- Move the file via the underlying storage mount directly
- Disable ProtectSameName if writing to the first matching backend is acceptable
- Delete the duplicate copy in one destination so the source resolves uniquely
Example fix
// before — ambiguous through alias fs.Move(ctx, "/alias/data/file.txt", "/alias/target") // after — address the concrete backend fs.Move(ctx, "/netdisk_a/docs/file.txt", "/netdisk_a/target")
Defensive patterns
Strategy: validation
Validate before calling
// Ensure the source path resolves in exactly one destination before moving
if len(d.pathMap[rootOf(srcPath)]) > 1 && d.ProtectSameName {
return errors.New("source is mirrored across destinations; move via a concrete mount")
} Type guard
// Go
func isSameNameErr(err error) bool {
return err != nil && strings.Contains(err.Error(), "same-name")
} Try / catch
if err := d.Move(ctx, src, dst); isSameNameErr(err) {
// retry against each concrete backend explicitly
} else if err != nil { return err } Prevention
- Use unique alias keys per destination for any mount you move files through
- Perform move operations on underlying mounts, not merged aliases
- Keep mirrors in sync externally rather than relying on alias writes
When it happens
Trigger: ProtectSameName=true, the same alias key mapped to 2+ destinations, the source file present in more than one of them, and a Move(srcObj, dstDir) call through the alias mount.
Common situations: Merged mirror mounts (same content mirrored to two storages) with protect-mode on; users try to reorganize files via the alias entry and hit the ambiguity guard on the file being moved.
Related errors
- same-name dirs cannot make sub-dir
- same-name dirs cannot be moved to
- same-name files cannot be Rename
- same-name dirs cannot be Put
- same-name files cannot be copied
AI-assisted analysis of AlistGo/alist@843d9dc814 (2026-08-15).
Data as JSON: /api/errors/b9931580fa9aa605.
Report an issue: GitHub.