krahets/hello-algo · error · Error

The Deque Is Empty.

Error message

The Deque Is Empty.

What it means

Thrown by peekFirst() on a circular-array deque when the deque is empty. peekFirst reads #nums[this.#front]; with queSize 0 the front slot holds stale data, so the guard prevents returning a garbage value. popFirst() calls peekFirst() internally, so the same throw surfaces from both.

Source

Thrown at codes/javascript/chapter_stack_and_queue/array_deque.js:88

    /* 队首出队 */
    popFirst() {
        const num = this.peekFirst();
        // 队首指针向后移动一位
        this.#front = this.index(this.#front + 1);
        this.#queSize--;
        return num;
    }

    /* 队尾出队 */
    popLast() {
        const num = this.peekLast();
        this.#queSize--;
        return num;
    }

    /* 访问队首元素 */
    peekFirst() {
        if (this.isEmpty()) throw new Error('The Deque Is Empty.');
        return this.#nums[this.#front];
    }

    /* 访问队尾元素 */
    peekLast() {
        if (this.isEmpty()) throw new Error('The Deque Is Empty.');
        // 计算尾元素索引
        const last = this.index(this.#front + this.#queSize - 1);
        return this.#nums[last];
    }

    /* 返回数组用于打印 */
    toArray() {
        // 仅转换有效长度范围内的列表元素
        const res = [];
        for (let i = 0, j = this.#front; i < this.#queSize; i++, j++) {
            res[i] = this.#nums[this.index(j)];
        }

View on GitHub (pinned to 69932aed18)

Solutions

  1. Check deque.isEmpty() (or size() === 0) before peekFirst/popFirst.
  2. Drain with while (!dq.isEmpty()) rather than a counted loop.
  3. Maintain a parallel counter or use a sentinel for empty-state signaling.
  4. Validate input batch sizes before processing.

Example fix

// before
const head = dq.peekFirst(); // throws if empty
// after
const head = dq.isEmpty() ? null : dq.peekFirst();
Defensive patterns

Strategy: validation

Validate before calling

function safePeekFirst(dq) {
  return dq.isEmpty() ? null : dq.peekFirst();
}

Type guard

function dequeNotEmpty(dq) {
  return dq.size() > 0;
}

Try / catch

try {
  const head = dq.peekFirst();
} catch (e) {
  if (e instanceof Error && e.message === 'The Deque Is Empty.') { /* handle empty */ } else throw e;
}

Prevention

When it happens

Trigger: Calling peekFirst()/popFirst() on a freshly constructed deque; calling after all elements were popped; off-by-one in a drain loop; reading the front of a deque that was never pushed to.

Common situations: Mismatched push/pop counts; BFS/DFS frontier draining; producer-consumer where the consumer races ahead.

Related errors


AI-assisted analysis of krahets/hello-algo@69932aed18 (2026-08-13). Data as JSON: /api/errors/8df851c3fb87e2f6. Report an issue: GitHub.