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 null

View on GitHub (pinned to 5c39e87a9a)

Solutions

  1. Guard with stack.isEmpty (or stack.length === 0) before pop().
  2. In drain loops, loop while (!stack.isEmpty) rather than a fixed iteration count.
  3. Ensure every error path still pushes or does not pop an extra time.
  4. 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

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.