{"record":{"id":"2fb2cfb9a4d83b66","repo":"qishibo/AnotherRedisDesktopManager","slug":"e-message-2fb2cf","errorCode":null,"errorMessage":"e.message","messagePattern":"e\\.message","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/components/DeleteBatch.vue","lineNumber":162,"sourceCode":"          // del 5000 keys one time\n          if (chunked.length >= 5000) {\n            delPromise = this.client.del(chunked);\n            chunked = [];\n          }\n        }\n\n        if (chunked.length) {\n          delPromise = this.client.del(chunked);\n        }\n        // use final promise\n        delPromise.then((reply) => {\n          if (reply > 0) {\n            this.afterDelete();\n          } else {\n            this.deleteFailed(this.$t('message.delete_failed'));\n          }\n        }).catch((e) => {\n          this.deleteFailed(e.message);\n        });\n      }\n\n      // cluster, one key per time instead of batch\n      else {\n        for (let i = 0; i < total; i++) {\n          delPromise = this.client.del(keys[i].key);\n          delPromise.catch((e) => {});\n        }\n\n        // use final promise\n        delPromise.then((reply) => {\n          if (reply == 1) {\n            this.afterDelete();\n          } else {\n            this.deleteFailed(this.$t('message.delete_failed'));\n          }\n        }).catch((e) => {","sourceCodeStart":144,"sourceCodeEnd":180,"githubUrl":"https://github.com/qishibo/AnotherRedisDesktopManager/blob/c149855106628babcdfb7675a8e7ba9434d2492a/src/components/DeleteBatch.vue#L144-L180","documentation":"The chunked DEL itself rejected in the non-cluster branch. DEL rarely fails for data reasons; a rejection means the command could not complete: connection lost, NOAUTH/NOPERM, READONLY replica, or a timeout on very large batches. The app routes the raw message to deleteFailed, which also resets the loading flags.","triggerScenarios":"Connection dropping between scan and delete; batch DEL on a replica with replica-read-only yes; ACL user without del permission; huge chunks hitting server or client timeouts.","commonSituations":"VPN blips during long cleanup, deleting against read replicas, least-privilege ACL users missing +del, chunk sizes in the thousands.","solutions":["Reconnect and retry the delete; the scanned list is still available","Verify the target is a writable primary and the user has +del","Reduce the chunk size passed to DEL so single batches stay under timeouts","On repeated failures, fall back to per-key deletes to isolate the bad key"],"exampleFix":"// before\ndelPromise.then((reply) => { /* ... */ }).catch((e) => {\n  this.deleteFailed(e.message);\n});\n\n// after\ndelPromise.then((reply) => { /* ... */ }).catch((e) => {\n  const m = String(e.message);\n  if (/NOPERM/i.test(m)) { this.deleteFailed(this.$t('message.no_permission_del')); }\n  else if (/READONLY/i.test(m)) { this.deleteFailed(this.$t('message.readonly_replica')); }\n  else { this.deleteFailed(e.message); }\n});","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":".catch((e) => {\n  const m = String(e.message);\n  if (/NOPERM|no permissions/i.test(m)) { /* ACL: request +del */ }\n  else if (/READONLY/i.test(m)) { /* route to primary */ }\n  else if (/ECONNRESET|closed/i.test(m)) { /* reconnect and retry once */ }\n  else { this.deleteFailed(m); }\n})","preventionTips":["Grant the GUI user +del (and +scan) in ACL setups","Delete against primaries only","Chunk DEL batches to a few hundred keys","Always route through deleteFailed so loading flags reset"],"tags":["redis","del","batch-delete","readonly","acl"],"backgroundTag":"redis-command-failed","analyzedSha":"c149855106628babcdfb7675a8e7ba9434d2492a","analyzedAt":"2026-08-22T09:06:28.613Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}