{"record":{"id":"bcc8732d8d02c0a1","repo":"AlistGo/alist","slug":"same-name-dirs-cannot-be-copied-to","errorCode":null,"errorMessage":"same-name dirs cannot be copied to","messagePattern":"same-name dirs cannot be copied to","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"drivers/alias/driver.go","lineNumber":192,"sourceCode":"\t\treturn errors.New(\"same-name files cannot be Rename\")\n\t}\n\treturn err\n}\n\nfunc (d *Alias) Copy(ctx context.Context, srcObj, dstDir model.Obj) error {\n\tif !d.Writable {\n\t\treturn errs.PermissionDenied\n\t}\n\tsrcPath, err := d.getReqPath(ctx, srcObj, false)\n\tif errs.IsNotImplement(err) {\n\t\treturn errors.New(\"same-name files cannot be copied\")\n\t}\n\tif err != nil {\n\t\treturn err\n\t}\n\tdstPath, err := d.getReqPath(ctx, dstDir, true)\n\tif errs.IsNotImplement(err) {\n\t\treturn errors.New(\"same-name dirs cannot be copied to\")\n\t}\n\tif err != nil {\n\t\treturn err\n\t}\n\t_, err = fs.Copy(ctx, *srcPath, *dstPath)\n\treturn err\n}\n\nfunc (d *Alias) Remove(ctx context.Context, obj model.Obj) error {\n\tif !d.Writable {\n\t\treturn errs.PermissionDenied\n\t}\n\treqPath, err := d.getReqPath(ctx, obj, false)\n\tif err == nil {\n\t\treturn fs.Remove(ctx, *reqPath)\n\t}\n\tif errs.IsNotImplement(err) {\n\t\treturn errors.New(\"same-name files cannot be Delete\")","sourceCodeStart":174,"sourceCodeEnd":210,"githubUrl":"https://github.com/AlistGo/alist/blob/843d9dc8149126976b2625911e45a4d3ffd6f2f5/drivers/alias/driver.go#L174-L210","documentation":"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.","triggerScenarios":"ProtectSameName=true; destination alias key mapped to multiple paths; destination folder present in two or more of them; Copy called targeting it.","commonSituations":"Copying into a merged folder backed by multiple storages that stay in sync (both contain the folder); aggregated 'archive' mounts used as copy targets.","solutions":["Copy to a single-destination alias key or underlying mount path","Disable ProtectSameName and accept first-match writes","Restructure Paths so write targets are never merged under one key"],"exampleFix":"# before\narchive: /disk_a/archive\narchive: /disk_b/archive\n\n# after\narchive_a: /disk_a/archive\narchive_b: /disk_b/archive","handlingStrategy":"validation","validationCode":"// Single-destination check on the copy target\nif len(d.pathMap[rootOf(dst)]) > 1 && d.ProtectSameName {\n    return errors.New(\"copy target mirrored; use a unique destination\")\n}","typeGuard":"// Go\nfunc isSameNameErr(err error) bool {\n    return err != nil && strings.Contains(err.Error(), \"same-name\")\n}","tryCatchPattern":"if err := d.Copy(ctx, src, dst); isSameNameErr(err) {\n    // re-issue the copy to a single-backend destination\n} else if err != nil { return err }","preventionTips":["Never use a merged mirror as a copy destination","Keep archive/copy targets single-backend by construction","Validate alias Paths config for duplicate keys before enabling writes"],"tags":["alias","protect-same-name","copy","destination"],"backgroundTag":null,"analyzedSha":"843d9dc8149126976b2625911e45a4d3ffd6f2f5","analyzedAt":"2026-08-15T12:14:11.722Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}