AlistGo/alist · error

same-name files cannot offline download

Error message

same-name files cannot offline download

What it means

Returned by Alias.PutURL when getReqPath on the destination directory fails with errs.NotImplement: with ProtectSameName enabled, the offline-download target folder exists in more than one destination sharing the alias key, so the driver cannot pick the backend that should receive the offline download.

Source

Thrown at drivers/alias/driver.go:238

	if err == nil {
		return fs.PutDirectly(ctx, *reqPath, s)
	}
	if errs.IsNotImplement(err) {
		return errors.New("same-name dirs cannot be Put")
	}
	return err
}

func (d *Alias) PutURL(ctx context.Context, dstDir model.Obj, name, url string) error {
	if !d.Writable {
		return errs.PermissionDenied
	}
	reqPath, err := d.getReqPath(ctx, dstDir, true)
	if err == nil {
		return fs.PutURL(ctx, *reqPath, name, url)
	}
	if errs.IsNotImplement(err) {
		return errors.New("same-name files cannot offline download")
	}
	return err
}

func (d *Alias) GetArchiveMeta(ctx context.Context, obj model.Obj, args model.ArchiveArgs) (model.ArchiveMeta, error) {
	root, sub := d.getRootAndPath(obj.GetPath())
	dsts, ok := d.pathMap[root]
	if !ok {
		return nil, errs.ObjectNotFound
	}
	for _, dst := range dsts {
		meta, err := d.getArchiveMeta(ctx, dst, sub, args)
		if err == nil {
			return meta, nil
		}
	}
	return nil, errs.NotImplement
}

View on GitHub (pinned to 843d9dc814)

Solutions

  1. Point the offline download at a uniquely-keyed destination or the underlying mount
  2. Disable ProtectSameName if first-match write behavior is acceptable
  3. Reserve offline-download targets as single-backend mounts

Example fix

// before
fs.PutURL(ctx, "/alias/queue", "ubuntu.iso", "https://mirror.example/ubuntu.iso")

// after
fs.PutURL(ctx, "/netdisk_a/queue", "ubuntu.iso", "https://mirror.example/ubuntu.iso")
Defensive patterns

Strategy: validation

Validate before calling

// Verify unique resolution for the offline-download target
if len(d.pathMap[rootOf(dst)]) > 1 && d.ProtectSameName {
    return errors.New("offline download target mirrored; choose one backend")
}

Type guard

// Go
func isSameNameErr(err error) bool {
    return err != nil && strings.Contains(err.Error(), "same-name")
}

Try / catch

if err := d.PutURL(ctx, dst, name, url); isSameNameErr(err) {
    // submit the offline task to the concrete storage instead
} else if err != nil { return err }

Prevention

When it happens

Trigger: ProtectSameName=true; multiple destinations under one alias key containing the target folder; PutURL (offline download / transfer task) issued against the alias path.

Common situations: Adding offline download tasks into a merged mount; ariac/transfer tooling pointed at an aggregated alias folder that is mirrored on several storages.

Related errors


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