{"record":{"id":"d345625bf9f2467a","repo":"AlistGo/alist","slug":"guangyapan-offline-download-only-supports-guangyap","errorCode":null,"errorMessage":"GuangYaPan offline download only supports GuangYaPan destination storage","messagePattern":"GuangYaPan offline download only supports GuangYaPan destination storage","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/offline_download/guangyapan/guangyapan.go","lineNumber":61,"sourceCode":"\tstorage, _, err := op.GetStorageAndActualPath(tempDir)\n\tif err != nil {\n\t\treturn false\n\t}\n\tif _, ok := storage.(*guangyapandriver.GuangYaPan); !ok {\n\t\treturn false\n\t}\n\treturn true\n}\n\nfunc (g *GuangYaPan) AddURL(args *tool.AddUrlArgs) (string, error) {\n\tg.refreshTaskCache = true\n\tstorage, actualPath, err := op.GetStorageAndActualPath(args.TempDir)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\tdriver, ok := storage.(*guangyapandriver.GuangYaPan)\n\tif !ok {\n\t\treturn \"\", errors.New(\"GuangYaPan offline download only supports GuangYaPan destination storage\")\n\t}\n\n\tctx := context.Background()\n\tif err := op.MakeDir(ctx, storage, actualPath); err != nil {\n\t\treturn \"\", err\n\t}\n\tparentDir, err := op.GetUnwrap(ctx, storage, actualPath)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\ttask, err := driver.OfflineDownload(ctx, args.Url, parentDir, \"\")\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"failed to add offline download task: %w\", err)\n\t}\n\treturn task.TaskID, nil\n}\n\nfunc (g *GuangYaPan) Remove(task *tool.DownloadTask) error {","sourceCodeStart":43,"sourceCodeEnd":79,"githubUrl":"https://github.com/AlistGo/alist/blob/843d9dc8149126976b2625911e45a4d3ffd6f2f5/internal/offline_download/guangyapan/guangyapan.go#L43-L79","documentation":"AddURL for the GuangYaPan offline download tool requires the destination TempDir to live on a GuangYaPan storage mount. It resolves the storage driver via op.GetStorageAndActualPath(args.TempDir) and type-asserts it to *guangyapandriver.GuangYaPan; any other driver type fails this guard. This keeps the tool from submitting offline tasks whose result files it cannot place.","triggerScenarios":"Calling GuangYaPan.AddURL with args.TempDir pointing at a path on a non-GuangYaPan storage mount (local, 123, WebDAV, ...). Also if TempDir resolution lands on the wrong mount because of path-prefix overlap in the mount table.","commonSituations":"The admin set the GuangYaPan temp dir setting to a path on another storage; a user selected a destination directory on a different mount; or the storage was recreated so the mount path changed since the task config was written.","solutions":["Set the GuangYaPan temp dir setting to a directory that is on a GuangYaPan storage mount","Make sure the destination path in the offline download request is inside the GuangYaPan mount","Verify the GuangYaPan storage is loaded and its mount path matches the temp dir prefix"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Before AddURL: confirm the temp dir lives on a GuangYaPan storage\nstorage, _, err := op.GetStorageAndActualPath(tempDir)\nif err != nil { return err }\nif _, ok := storage.(*guangyapandriver.GuangYaPan); !ok {\n    return fmt.Errorf(\"temp dir %s is not on GuangYaPan storage\", tempDir)\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Configure the GuangYaPan temp dir setting on the GuangYaPan mount at setup time","Validate the temp dir setting after any storage reconfiguration","Surface the mount path requirement in the tool's UI description"],"tags":["offline-download","guangyapan","storage-mount","type-assertion"],"backgroundTag":null,"analyzedSha":"843d9dc8149126976b2625911e45a4d3ffd6f2f5","analyzedAt":"2026-08-15T12:14:11.722Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}