Blocking retrieval #EC3: Client receiving unexpected response

I’m stuck on Stage Blocking retrieval #EC3.

I have implemented BLPOP command with proxies and promises. but I keep getting an error that client 1 ( first subscriber of blpop ) received a different response. Maybe I didn’t understand the behavior of this command well enough. Please ignore the context from “your program” logs below if its confusing.

Here are my logs:

[compile] Moved ./.codecrafters/run.sh → ./your_program.sh
[compile] Compilation successful.
[tester::#EC3] Running tests for Stage #EC3 (Lists - Blocking retrieval)
[tester::#EC3] $ ./your_program.sh
[your_program] {"level":"INFO","time":"2026-04-29T08:14:37.267Z","context":{},"msg":"Logs from your program will appear here!"}
[tester::#EC3] [client-1] $ redis-cli BLPOP blueberry 0
[tester::#EC3] [client-2] $ redis-cli BLPOP blueberry 0
[tester::#EC3] [client-3] $ redis-cli RPUSH blueberry raspberry
[your_program] {"level":"INFO","time":"2026-04-29T08:14:37.324Z","context":{"traceId":"9f149790-2ad4-4517-a1bd-1f62bd7ccf02"},"msg":"BLPOP"}
[your_program] {"level":"INFO","time":"2026-04-29T08:14:37.324Z","context":{"traceId":"afc85221-5dff-476f-8127-dbcb7a65ffd5"},"msg":"BLPOP"}
[your_program] {"level":"INFO","time":"2026-04-29T08:14:37.325Z","context":{"traceId":"b94e6091-adf1-4e26-9854-fe6229483cf3"},"msg":"RPUSH"}
[your_program] {"level":"INFO","time":"2026-04-29T08:14:37.325Z","context":{"traceId":"b94e6091-adf1-4e26-9854-fe6229483cf3"},"msg":"Time Taken for execution - 1"}
[your_program] {"level":"INFO","time":"2026-04-29T08:14:37.325Z","context":{"traceId":"b94e6091-adf1-4e26-9854-fe6229483cf3"},"msg":"calling mutation observers - 2"}
[your_program] {"level":"INFO","time":"2026-04-29T08:14:37.325Z","context":{"traceId":"b94e6091-adf1-4e26-9854-fe6229483cf3"},"msg":"triggering callback"}
[your_program] {"level":"INFO","time":"2026-04-29T08:14:37.325Z","context":{"traceId":"b94e6091-adf1-4e26-9854-fe6229483cf3"},"msg":"triggering callback"}
[your_program] {"level":"INFO","time":"2026-04-29T08:14:37.325Z","context":{"traceId":"9f149790-2ad4-4517-a1bd-1f62bd7ccf02"},"msg":"result - blueberry,raspberry"}
[your_program] {"level":"INFO","time":"2026-04-29T08:14:37.325Z","context":{"traceId":"afc85221-5dff-476f-8127-dbcb7a65ffd5"},"msg":"result - blueberry,raspberry"}
[your_program] {"level":"INFO","time":"2026-04-29T08:14:37.325Z","context":{"traceId":"9f149790-2ad4-4517-a1bd-1f62bd7ccf02"},"msg":"Time Taken for execution - 1"}
[your_program] {"level":"INFO","time":"2026-04-29T08:14:37.325Z","context":{"traceId":"afc85221-5dff-476f-8127-dbcb7a65ffd5"},"msg":"Time Taken for execution - 1"}
[tester::#EC3] [client-3] ✔︎ Received 1
[tester::#EC3] Expecting 1 client to receive response of BLPOP command
[tester::#EC3] [client-2] ✔︎ Received ["blueberry", "raspberry"]
[tester::#EC3] [client-1] Expecting no response
[tester::#EC3] client-1 received unexpected response: "*2\r\n$9\r\nblueberry\r\n$9\r\nraspberry\r\n"
[tester::#EC3] Test failed

And here’s a snippet of my code:

const { logger } = require("../contextualLogger");
const { redisLookup } = require("../inMemoryLookup/index");
const {
  encodeToRespBulkString,
  encodeToRespArray,
} = require("../respParser/index");

const observersLookup = new Map();

function createObservableArray() {
  let timeout;
  let isManualMutation = false;

  const observed = new Proxy([], {
    set(target, prop, value) {
      target[prop] = value;
      if (!isManualMutation && observersLookup.get(observed)) {
        // Clear and reset a timer so the logic runs only ONCE after the last set
        clearTimeout(timeout);
        timeout = setTimeout(() => {
          isManualMutation = true;
          const removedValue = observed.shift();
          const callbacks = observersLookup.get(observed);
          logger.info(`calling mutation observers - ${callbacks.length}`);
          callbacks.forEach((cb) => cb(removedValue));
          observersLookup.delete(observed);
          isManualMutation = false;
        }, 0);
      }

      return true;
    },
  });

  return observed;
}

async function blPopCommand(listName, timer = 0) {
  timer = +timer;
  let list = redisLookup[listName];

  if (!list) {
    list = createObservableArray();
    redisLookup[listName] = list;
  }

  let result;

  if (!list[0]) {
    let observersList = observersLookup.get(list);
    if (!observersList) {
      observersList = [];
      observersLookup.set(list, observersList);
    }
    result = await new Promise((res, rej) => {
      const callback = (removedValue) => {
        logger.info("triggering callback");
        res([listName, removedValue]);
      };
      observersList.push(callback);
      if (timer) {
        logger.info(`setting timer - ${timer}`);
        setTimeout(() => {
          observersLookup.set(
            list,
            observersList.filter((cb) => cb !== callback),
          );
          res([]);
        }, timer * 1000);
      }
    });
    logger.info(`result - ${result}`);
  } else {
    const removedValue = list.shift();
    result = [listName, removedValue];
  }

  const res = encodeToRespArray(result.map(encodeToRespBulkString));
  return res;
}

module.exports = {
  blPopCommand,
};

I am attaching my github repo link with main.js files as well
CC Redis - main.js

Hey @VIGNESHWAR-RV, could you check if you’ve ensured that only one blocked client can receive the popped element, when multiple clients are blocked on the same list?

Let me know if you need help debugging this further.

ohh. I didn’t ensure only one client should receive the popped element. I thought the popped element should be notified to all the clients ( starting with longest waiting client a.k.a first blocked client ( client 1 )).
is it like only the first blocked client should be responded and not any others ?.
Incase of multiple elements added to the list, should the behavior remain same with only one client ? or should we notify all the blocking clients with subsequent popped elements from the list ?.