node-redis icon indicating copy to clipboard operation
node-redis copied to clipboard

Unhandled promise rejection triggered in DoublyLinkedList after executeTask()

Open udnes99 opened this issue 4 months ago • 5 comments

Description

We just detected an unhandled promise rejection that was triggered while issuing a command or a .execute() using a pool instance. Due to limited stack trace, I am not sure if it was a dedicated client obtained by .execute() or just a client retrieved for the execution of a single command. I am not that familiar with the internals of the Redis SDK, but I am guessing some kind of race condition within the library related to the acquisition and release of client instances for tasks, or some bug in the linked list.

Node.js Version

22.18.0

Redis Server Version

7.4.0

Node Redis Version

5.8.0

Platform

Linux

Logs

TypeError: Cannot set properties of undefined (setting 'next')
  File "/app/node_modules/.pnpm/@[email protected]/node_modules/@redis/client/dist/lib/client/linked-list.js", line 76, col 32, in DoublyLinkedList.remove
    node.previous.next = node.next;
  File "/app/node_modules/.pnpm/@[email protected]/node_modules/@redis/client/dist/lib/client/pool.js", line 262, col 28, in #returnClient
    this.#clientsInUse.remove(node);
  File "/app/node_modules/.pnpm/@[email protected]/node_modules/@redis/client/dist/lib/client/pool.js", line 248, col 50
    .finally(() => this.#returnClient(node));
  File "<anonymous>"

udnes99 avatar Aug 19 '25 13:08 udnes99

Hi @udnes99, thanks for raising this issue. I can easily patch the current TypeError that you are experiencing, but i have the suspicion that there is another problem that is hiding here. And that problem is gonna be hard to find tbh. If you are able to narrow it down somehow on your side, that would be great.

nkaradzhov avatar Aug 20 '25 12:08 nkaradzhov

Hi @udnes99, thanks for raising this issue. I can easily patch the current TypeError that you are experiencing, but i have the suspicion that there is another problem that is hiding here. And that problem is gonna be hard to find tbh. If you are able to narrow it down somehow on your side, that would be great.

I understand! Like I said, I am not that familiar with the internals of this library. I am not sure what the conditions are for triggering it; it seems sporadic on our side. I suspect there is some sort of race condition. I can try to look through the code, though.

udnes99 avatar Aug 22 '25 11:08 udnes99

I get the same error consistently for the following code:

//repro.ts
import { createClientPool } from "redis";

const client = createClientPool({ url: "redis://bad-host:6379" });
client.on("error", console.error);

try {
  await client.get("key");
} catch (err) {
  console.error(err);
  client.destroy();
}

michal-billtech avatar Sep 17 '25 14:09 michal-billtech

@nkaradzhov could you please look at the code sample I sent? Maybe I'm doing something wrong but currently I'm unable to properly cleanup a client pool without causing unhandled rejection.

michal-billtech avatar Sep 19 '25 12:09 michal-billtech

Hi @nkaradzhov, let me know if my attempt PR would help mitigate this issue, thank you

ntvviktor avatar Sep 22 '25 04:09 ntvviktor