AlistGo/alist · error

same-name files cannot be copied

Error message

same-name files cannot be copied

What it means

Returned by Alias.Copy when the SOURCE file cannot be uniquely resolved: getReqPath(srcObj) fails with errs.NotImplement because ProtectSameName is on and the source exists in multiple destinations mapped under one alias key. The driver will not guess which copy to read from.

Source

Thrown at drivers/alias/driver.go:185

		return errs.PermissionDenied
	}
	reqPath, err := d.getReqPath(ctx, srcObj, false)
	if err == nil {
		return fs.Rename(ctx, *reqPath, newName)
	}
	if errs.IsNotImplement(err) {
		return errors.New("same-name files cannot be Rename")
	}
	return err
}

func (d *Alias) Copy(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 copied")
	}
	if err != nil {
		return err
	}
	dstPath, err := d.getReqPath(ctx, dstDir, true)
	if errs.IsNotImplement(err) {
		return errors.New("same-name dirs cannot be copied to")
	}
	if err != nil {
		return err
	}
	_, err = fs.Copy(ctx, *srcPath, *dstPath)
	return err
}

func (d *Alias) Remove(ctx context.Context, obj model.Obj) error {
	if !d.Writable {
		return errs.PermissionDenied

View on GitHub (pinned to 843d9dc814)

Solutions

  1. Copy from a uniquely-keyed alias or directly from the underlying mount
  2. Disable ProtectSameName (first-resolved destination wins)
  3. Keep one authoritative copy and mount the others under different keys
  4. Script the copy per mirror explicitly when you truly want all copies

Example fix

// before
fs.Copy(ctx, "/alias/data/file.bin", "/alias/backup")

// after
fs.Copy(ctx, "/netdisk_a/docs/file.bin", "/netdisk_a/backup")
Defensive patterns

Strategy: validation

Validate before calling

// Ensure single-source resolution before copying through alias
if len(d.pathMap[rootOf(src)]) > 1 && d.ProtectSameName {
    return errors.New("source mirrored; copy from 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.Copy(ctx, src, dst); isSameNameErr(err) {
    // copy from /netdisk_a/... explicitly
} else if err != nil { return err }

Prevention

When it happens

Trigger: ProtectSameName=true; alias key with 2+ destinations both containing the source file; Copy(srcObj, dstDir) called through the alias mount.

Common situations: Copy operations out of a merged mirror mount; deduplicated backups where the same relative path exists on several storages under one alias name.

Related errors


AI-assisted analysis of AlistGo/alist@843d9dc814 (2026-08-15). Data as JSON: /api/errors/2acaad99399b9072. Report an issue: GitHub.