AlistGo/alist · error

same-name dirs cannot be copied to

Error message

same-name dirs cannot be copied to

What it means

Returned by Alias.Copy when the DESTINATION directory is ambiguous: getReqPath(dstDir) fails with errs.NotImplement because ProtectSameName is enabled and the destination folder resolves in more than one destination sharing the alias key. The source was fine; where to write the copy is not decidable.

Source

Thrown at drivers/alias/driver.go:192

		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
	}
	reqPath, err := d.getReqPath(ctx, obj, false)
	if err == nil {
		return fs.Remove(ctx, *reqPath)
	}
	if errs.IsNotImplement(err) {
		return errors.New("same-name files cannot be Delete")

View on GitHub (pinned to 843d9dc814)

Solutions

  1. Copy to a single-destination alias key or underlying mount path
  2. Disable ProtectSameName and accept first-match writes
  3. Restructure Paths so write targets are never merged under one key

Example fix

# before
archive: /disk_a/archive
archive: /disk_b/archive

# after
archive_a: /disk_a/archive
archive_b: /disk_b/archive
Defensive patterns

Strategy: validation

Validate before calling

// Single-destination check on the copy target
if len(d.pathMap[rootOf(dst)]) > 1 && d.ProtectSameName {
    return errors.New("copy target mirrored; use a unique destination")
}

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) {
    // re-issue the copy to a single-backend destination
} else if err != nil { return err }

Prevention

When it happens

Trigger: ProtectSameName=true; destination alias key mapped to multiple paths; destination folder present in two or more of them; Copy called targeting it.

Common situations: Copying into a merged folder backed by multiple storages that stay in sync (both contain the folder); aggregated 'archive' mounts used as copy targets.

Related errors


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