krahets/hello-algo · error · Error
The Deque Is Empty.
Error message
The Deque Is Empty.
What it means
An Error 'The Deque Is Empty.' thrown by peekFirst() in ArrayDeque (array_deque.ts:88). peekFirst() returns nums[front], which is meaningless when queSize === 0 because front points at stale or uninitialized data. Both pop methods (popFirst/popLast) call a peek first, so this guard also protects pops from operating on an empty ring buffer.
Source
Thrown at zh-hant/codes/typescript/chapter_stack_and_queue/array_deque.ts:88
/* 佇列首出列 */
popFirst(): number {
const num: number = this.peekFirst();
// 佇列首指標向後移動一位
this.front = this.index(this.front + 1);
this.queSize--;
return num;
}
/* 佇列尾出列 */
popLast(): number {
const num: number = this.peekLast();
this.queSize--;
return num;
}
/* 訪問佇列首元素 */
peekFirst(): number {
if (this.isEmpty()) throw new Error('The Deque Is Empty.');
return this.nums[this.front];
}
/* 訪問佇列尾元素 */
peekLast(): number {
if (this.isEmpty()) throw new Error('The Deque Is Empty.');
// 計算尾元素索引
const last = this.index(this.front + this.queSize - 1);
return this.nums[last];
}
/* 返回陣列用於列印 */
toArray(): number[] {
// 僅轉換有效長度範圍內的串列元素
const res: number[] = [];
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
- Check deque.isEmpty() (or deque.size() === 0) before peekFirst/popFirst.
- Loop with `while (!deque.isEmpty())` when draining.
- Remember capacity() is the backing array length, not the element count — use size() for the latter.
- Keep push and pop counts balanced, or cache the count you intend to consume.
Example fix
// before: peeking an empty deque throws const head = deque.peekFirst(); // after: guard with emptiness check const head = deque.isEmpty() ? undefined : deque.peekFirst();
Defensive patterns
Strategy: validation
Validate before calling
// Guard the head end of an ArrayDeque
function safePeekFirst(deque: ArrayDeque): number | undefined {
return deque.isEmpty() ? undefined : deque.peekFirst();
}
if (!deque.isEmpty()) {
const head = deque.popFirst();
} Type guard
const nonEmpty = (deque: ArrayDeque): boolean => !deque.isEmpty();
Try / catch
try {
const head = deque.peekFirst();
} catch (e) {
if (e instanceof Error && /Deque Is Empty/.test(e.message)) {
// deque drained; handle empty state
} else throw e;
} Prevention
- Check isEmpty() before any peekFirst/popFirst.
- Use size() for element count; capacity() is the backing array length.
- Keep push and pop counts balanced per session.
- Drain with `while (!deque.isEmpty())`.
When it happens
Trigger: Calling deque.peekFirst() or deque.popFirst() when deque.isEmpty() is true (queSize === 0). Popping more elements than were pushed, or peeking a deque that was just constructed with `new ArrayDeque(capacity)` and never filled.
Common situations: Unbalanced push/pop counts in a ring-buffer deque; assuming a peek is safe because capacity > 0 (capacity is storage size, not element count); draining the deque in a loop without an emptiness check; calling popFirst after popLast already emptied it.
Related errors
AI-assisted analysis of krahets/hello-algo@69932aed18 (2026-08-13).
Data as JSON: /api/errors/45af093ad5a0ff23.
Report an issue: GitHub.