{"record":{"id":"b40f596c8341b56d","repo":"AlistGo/alist","slug":"failed-to-add-offline-download-task-w-b40f59","errorCode":null,"errorMessage":"failed to add offline download task: %w","messagePattern":"failed to add offline download task: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/offline_download/guangyapan/guangyapan.go","lineNumber":74,"sourceCode":"\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 {\n\tstorage, _, err := op.GetStorageAndActualPath(task.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\tctx := context.Background()\n\tif err := driver.DeleteOfflineTasks(ctx, []string{task.GID}, false); err != nil {\n\t\treturn err\n\t}\n\tg.DelTaskCache(driver, task.GID)","sourceCodeStart":56,"sourceCodeEnd":92,"githubUrl":"https://github.com/AlistGo/alist/blob/843d9dc8149126976b2625911e45a4d3ffd6f2f5/internal/offline_download/guangyapan/guangyapan.go#L56-L92","documentation":"GuangYaPan.AddURL() calls driver.OfflineDownload() after making the parent directory, and wraps any failure with 'failed to add offline download task'. The real cause is in the wrapped error: authentication loss, unsupported/invalid URL, quota exhaustion, or an API error from the GuangYaPan service.","triggerScenarios":"Posting an offline download URL via the API with tool=guangyapan when the driver's stored token/cookie has expired, the URL is not a direct download link the service accepts, or the account hit its offline-download task quota.","commonSituations":"GuangYaPan login credentials expired since the storage was added; user pastes a magnet or streaming page URL the platform rejects; rate limiting after adding many tasks in a burst.","solutions":["Read the wrapped (%w) error text to identify the underlying cause first","Refresh the storage's authentication (re-login / update token) in the storage settings and retry","Verify the URL is a supported direct download link by testing it on the GuangYaPan site","Retry after a delay if the wrapped error indicates rate limiting or quota"],"exampleFix":"task, err := driver.OfflineDownload(ctx, args.Url, parentDir, \"\")\nif err != nil {\n    return \"\", fmt.Errorf(\"failed to add offline download task: %w\", err)\n}\n\n// caller: unwrap to distinguish auth vs URL problems\nvar apiErr *panErr.APIError\nif errors.As(err, &apiErr) && apiErr.Code == codeUnauthorized {\n    // refresh credentials then retry once\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"gid, err := g.AddURL(args)\nif err != nil {\n    if strings.Contains(err.Error(), \"failed to add offline download task\") {\n        cause := errors.Unwrap(err)\n        if isAuthError(cause) {\n            refreshGuangYaPanAuth(storage) // then let the user retry once\n        }\n        return fmt.Errorf(\"guangyapan rejected the task: %v\", cause)\n    }\n    return err\n}","preventionTips":["Keep GuangYaPan credentials fresh; monitor auth-expiry errors and alert","Test questionable links on the provider's site before queuing them","Log the unwrapped cause, not just the wrapper, in task failure records"],"tags":["guangyapan","offline-download","auth","error-wrapping"],"backgroundTag":null,"analyzedSha":"843d9dc8149126976b2625911e45a4d3ffd6f2f5","analyzedAt":"2026-08-15T12:14:11.722Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}