TheAlgorithms/JavaScript · error · Error
Stack Underflow
Error message
Stack Underflow
What it means
Thrown by Stack.pop() (plain Error 'Stack Underflow') when this.top === 0, i.e. the stack is empty. The Stack tracks size via a top counter initialized to 0 and incremented by push; pop decrements it, so a pop on an empty stack (top === 0) is rejected rather than returning undefined.
Source
Thrown at Data-Structures/Stack/StackES6.js:30
class Stack {
constructor() {
this.stack = []
this.top = 0
}
// Adds a value to the end of the Stack
push(newValue) {
this.stack.push(newValue)
this.top += 1
}
// Returns and removes the last element of the Stack
pop() {
if (this.top !== 0) {
this.top -= 1
return this.stack.pop()
}
throw new Error('Stack Underflow')
}
// Returns the number of elements in the Stack
get length() {
return this.top
}
// Returns true if stack is empty, false otherwise
get isEmpty() {
return this.top === 0
}
// Returns the last element without removing it
get last() {
if (this.top !== 0) {
return this.stack[this.stack.length - 1]
}
return nullView on GitHub (pinned to 5c39e87a9a)
Solutions
- Guard with stack.isEmpty (or stack.length === 0) before pop().
- In drain loops, loop while (!stack.isEmpty) rather than a fixed iteration count.
- Ensure every error path still pushes or does not pop an extra time.
- Wrap pop in try/catch if underflow is expected control flow (e.g. optional frame).
Example fix
// before const v = stack.pop() // throws once empty // after const v = stack.isEmpty ? undefined : stack.pop()
Defensive patterns
Strategy: validation
Validate before calling
function safePop(stack) {
return stack.isEmpty ? undefined : stack.pop()
} Type guard
const isNonEmpty = (stack) => !stack.isEmpty
Try / catch
try {
return stack.pop()
} catch (e) {
if (e instanceof Error && /underflow/i.test(e.message)) return undefined
throw e
} Prevention
- Loop with while (!stack.isEmpty) rather than a fixed pop count.
- Audit error paths to ensure no extra pop fires when a push was skipped.
- In evaluators, validate token counts before popping operands.
- Wrap pop to return undefined when underflow is expected control flow.
When it happens
Trigger: Calling pop() more times than push(); calling pop() on a freshly constructed stack; unbalanced push/pop after an exception path skipped a push.
Common situations: Recursion/emulation that pops cleanup frames twice; expression evaluators that over-pop on malformed input; tests popping more samples than they pushed.
Related errors
AI-assisted analysis of TheAlgorithms/JavaScript@5c39e87a9a (2026-08-13).
Data as JSON: /api/errors/4587a5e957ceda50.
Report an issue: GitHub.