{"record":{"id":"991c71755a2048d5","repo":"AlistGo/alist","slug":"same-name-files-cannot-offline-download","errorCode":null,"errorMessage":"same-name files cannot offline download","messagePattern":"same-name files cannot offline download","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"drivers/alias/driver.go","lineNumber":238,"sourceCode":"\tif err == nil {\n\t\treturn fs.PutDirectly(ctx, *reqPath, s)\n\t}\n\tif errs.IsNotImplement(err) {\n\t\treturn errors.New(\"same-name dirs cannot be Put\")\n\t}\n\treturn err\n}\n\nfunc (d *Alias) PutURL(ctx context.Context, dstDir model.Obj, name, url string) error {\n\tif !d.Writable {\n\t\treturn errs.PermissionDenied\n\t}\n\treqPath, err := d.getReqPath(ctx, dstDir, true)\n\tif err == nil {\n\t\treturn fs.PutURL(ctx, *reqPath, name, url)\n\t}\n\tif errs.IsNotImplement(err) {\n\t\treturn errors.New(\"same-name files cannot offline download\")\n\t}\n\treturn err\n}\n\nfunc (d *Alias) GetArchiveMeta(ctx context.Context, obj model.Obj, args model.ArchiveArgs) (model.ArchiveMeta, error) {\n\troot, sub := d.getRootAndPath(obj.GetPath())\n\tdsts, ok := d.pathMap[root]\n\tif !ok {\n\t\treturn nil, errs.ObjectNotFound\n\t}\n\tfor _, dst := range dsts {\n\t\tmeta, err := d.getArchiveMeta(ctx, dst, sub, args)\n\t\tif err == nil {\n\t\t\treturn meta, nil\n\t\t}\n\t}\n\treturn nil, errs.NotImplement\n}","sourceCodeStart":220,"sourceCodeEnd":256,"githubUrl":"https://github.com/AlistGo/alist/blob/843d9dc8149126976b2625911e45a4d3ffd6f2f5/drivers/alias/driver.go#L220-L256","documentation":"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.","triggerScenarios":"ProtectSameName=true; multiple destinations under one alias key containing the target folder; PutURL (offline download / transfer task) issued against the alias path.","commonSituations":"Adding offline download tasks into a merged mount; ariac/transfer tooling pointed at an aggregated alias folder that is mirrored on several storages.","solutions":["Point the offline download at a uniquely-keyed destination or the underlying mount","Disable ProtectSameName if first-match write behavior is acceptable","Reserve offline-download targets as single-backend mounts"],"exampleFix":"// before\nfs.PutURL(ctx, \"/alias/queue\", \"ubuntu.iso\", \"https://mirror.example/ubuntu.iso\")\n\n// after\nfs.PutURL(ctx, \"/netdisk_a/queue\", \"ubuntu.iso\", \"https://mirror.example/ubuntu.iso\")","handlingStrategy":"validation","validationCode":"// Verify unique resolution for the offline-download target\nif len(d.pathMap[rootOf(dst)]) > 1 && d.ProtectSameName {\n    return errors.New(\"offline download target mirrored; choose one backend\")\n}","typeGuard":"// Go\nfunc isSameNameErr(err error) bool {\n    return err != nil && strings.Contains(err.Error(), \"same-name\")\n}","tryCatchPattern":"if err := d.PutURL(ctx, dst, name, url); isSameNameErr(err) {\n    // submit the offline task to the concrete storage instead\n} else if err != nil { return err }","preventionTips":["Point offline-download queues at single-backend mounts","Remember the underlying storage must itself support offline download for the fallback to work","Avoid mirrored queues: offline tasks are stateful and cannot be ambiguous"],"tags":["alias","protect-same-name","offline-download","put-url"],"backgroundTag":null,"analyzedSha":"843d9dc8149126976b2625911e45a4d3ffd6f2f5","analyzedAt":"2026-08-15T12:14:11.722Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}