{"record":{"id":"905e39c96aa2cccd","repo":"AlistGo/alist","slug":"failed-to-delete-qbittorrent-task","errorCode":null,"errorMessage":"failed to delete qbittorrent task","messagePattern":"failed to delete qbittorrent task","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/qbittorrent/client.go","lineNumber":353,"sourceCode":"\t}\n\n\tinfo, err := c.GetInfo(id)\n\tif err != nil {\n\t\treturn err\n\t}\n\tv := url.Values{}\n\tv.Set(\"hashes\", info.Hash)\n\tif deleteFiles {\n\t\tv.Set(\"deleteFiles\", \"true\")\n\t} else {\n\t\tv.Set(\"deleteFiles\", \"false\")\n\t}\n\tresponse, err := c.post(\"/api/v2/torrents/delete\", v)\n\tif err != nil {\n\t\treturn err\n\t}\n\tif response.StatusCode != 200 {\n\t\treturn errors.New(\"failed to delete qbittorrent task\")\n\t}\n\n\tv = url.Values{}\n\tv.Set(\"tags\", \"alist-\"+id)\n\tresponse, err = c.post(\"/api/v2/torrents/deleteTags\", v)\n\tif err != nil {\n\t\treturn err\n\t}\n\tif response.StatusCode != 200 {\n\t\treturn errors.New(\"failed to delete qbittorrent tag\")\n\t}\n\treturn nil\n}\n","sourceCodeStart":335,"sourceCodeEnd":367,"githubUrl":"https://github.com/AlistGo/alist/blob/843d9dc8149126976b2625911e45a4d3ffd6f2f5/pkg/qbittorrent/client.go#L335-L367","documentation":"POSTing to /api/v2/torrents/delete with the torrent hash and deleteFiles flag returned a non-200 status. The torrent removal itself failed before tag cleanup is attempted.","triggerScenarios":"Calling DeleteTorrent with a stale/already-removed hash, an unauthorized session (403), or when qBittorrent cannot delete files from disk (permission error surfaces as non-200).","commonSituations":"Torrent was manually deleted from qBittorrent between listing and deleting; qBittorrent restarted (session reset); the alist tag \"alist-<id>\" already removed.","solutions":["Treat an already-deleted torrent as success (idempotent delete) by listing hashes first and skipping missing ones","Check authorization by re-logging in if status is 403","Inspect qBittorrent logs for file-deletion permission failures when deleteFiles=true"],"exampleFix":"// before\nif err := c.DeleteTorrent(info, true, id); err != nil { return err }\n\n// after\nif err := c.DeleteTorrent(info, true, id); err != nil {\n    if strings.Contains(err.Error(), \"failed to delete qBittorrent task\") {\n        // verify whether it still exists; treat missing as success\n        if !c.TorrentExists(info.Hash) { return nil }\n    }\n    return err\n}","handlingStrategy":"try-catch","validationCode":"hashes, _ := c.ListTorrentHashes()\nif !sliceContains(hashes, info.Hash) {\n\treturn nil // already gone; nothing to do\n}","typeGuard":null,"tryCatchPattern":"err := c.DeleteTorrent(info, deleteFiles, id)\nif err != nil && strings.Contains(err.Error(), \"failed to delete qbittorrent task\") {\n\tif !c.TorrentExists(info.Hash) { return nil } // idempotent\n\treturn err\n}","preventionTips":["Make delete flows idempotent by checking existence first","Re-login on 403 before treating delete as permanently failed"],"tags":["qbittorrent","delete","torrent","offline-download"],"backgroundTag":null,"analyzedSha":"843d9dc8149126976b2625911e45a4d3ffd6f2f5","analyzedAt":"2026-08-15T12:14:11.722Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}