{"record":{"id":"600133366becdcf1","repo":"AlistGo/alist","slug":"unsupported-storage-driver-for-offline-download-o-600133","errorCode":null,"errorMessage":"unsupported storage driver for offline download, only Pikpak is supported","messagePattern":"unsupported storage driver for offline download, only Pikpak is supported","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/offline_download/pikpak/pikpak.go","lineNumber":62,"sourceCode":"\tif err != nil {\n\t\treturn false\n\t}\n\tif _, ok := storage.(*pikpak.PikPak); !ok {\n\t\treturn false\n\t}\n\treturn true\n}\n\nfunc (p *PikPak) AddURL(args *tool.AddUrlArgs) (string, error) {\n\t// 添加新任务刷新缓存\n\tp.refreshTaskCache = true\n\tstorage, actualPath, err := op.GetStorageAndActualPath(args.TempDir)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\tpikpakDriver, ok := storage.(*pikpak.PikPak)\n\tif !ok {\n\t\treturn \"\", fmt.Errorf(\"unsupported storage driver for offline download, only Pikpak is supported\")\n\t}\n\n\tctx := context.Background()\n\n\tif err := op.MakeDir(ctx, storage, actualPath); err != nil {\n\t\treturn \"\", err\n\t}\n\n\tparentDir, err := op.GetUnwrap(ctx, storage, actualPath)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\tt, err := pikpakDriver.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","sourceCodeStart":44,"sourceCodeEnd":80,"githubUrl":"https://github.com/AlistGo/alist/blob/843d9dc8149126976b2625911e45a4d3ffd6f2f5/internal/offline_download/pikpak/pikpak.go#L44-L80","documentation":"PikPak.AddURL() resolves storage from args.TempDir and type-asserts it to *pikpak.PikPak before submitting the offline task. Any other driver behind the mount fails the assertion. PikPak offline downloads must target a PikPak storage mount because the file lands directly in that cloud drive.","triggerScenarios":"Adding an offline URL with tool=pikpak while args.TempDir is on local storage or a non-PikPak cloud mount; the PikPak storage was unmounted between task creation and add.","commonSituations":"Tool/directory mismatch in the offline download settings UI; users assuming PikPak downloads to server disk; mount path prefix shadowed by another storage.","solutions":["Point the temp/save directory at the PikPak storage mount","Or pick the tool that matches the destination storage (http/aria2 for local)","Confirm the storage's driver reads 'PikPak' in the admin storages list"],"exampleFix":"// before\n{ \"tool\": \"pikpak\", \"temp_dir\": \"/local/tmp\" }\n\n// after\n{ \"tool\": \"pikpak\", \"temp_dir\": \"/pikpak/tmp\" }","handlingStrategy":"type-guard","validationCode":"storage, _, err := op.GetStorageAndActualPath(args.TempDir)\nif err != nil {\n    return err\n}\nif storage.Driver != \"PikPak\" {\n    return fmt.Errorf(\"pikpak tool requires a PikPak mount, got %s\", storage.Driver)\n}","typeGuard":"func asPikPak(tempDir string) (*pikpak.PikPak, error) {\n    storage, _, err := op.GetStorageAndActualPath(tempDir)\n    if err != nil {\n        return nil, err\n    }\n    d, ok := storage.(*pikpak.PikPak)\n    if !ok {\n        return nil, fmt.Errorf(\"%s is on %q storage, need PikPak\", tempDir, storage.Driver)\n    }\n    return d, nil\n}","tryCatchPattern":"if _, err := p.AddURL(args); err != nil {\n    if strings.Contains(err.Error(), \"only Pikpak is supported\") {\n        return userError(\"select a PikPak storage directory for this tool\")\n    }\n    return err\n}","preventionTips":["Dedicate one temp dir per tool and validate driver match at creation","Expose driver names in UI tool selection to prevent mismatch","Unit-test AddURL with a non-PikPak storage to keep the guard honest"],"tags":["pikpak","storage-driver","type-assertion","offline-download"],"backgroundTag":null,"analyzedSha":"843d9dc8149126976b2625911e45a4d3ffd6f2f5","analyzedAt":"2026-08-15T12:14:11.722Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}