oxc-project/oxc · warning

Cannot pop all entries

Error message

Cannot pop all entries

What it means

Diagnostic from oxlint's vue/require-prop-types rule (crates/oxc_linter/src/rules/vue/require_prop_types.rs). Every declared prop must carry at least a type definition. It reports array-syntax props (`props: ['foo']`) and object entries lacking a `type` key. Without types Vue performs no validation and IDEs cannot infer the prop's shape, so bad data flows through unchecked.

Source

Thrown at crates/oxc_data_structures/src/stack/non_empty.rs:320

    }

    /// Pop value from stack.
    ///
    /// # Panics
    /// Panics if the stack has only 1 entry on it.
    #[inline]
    pub fn pop(&mut self) -> T {
        // Panic if trying to remove last entry from stack.
        //
        // Putting the panic in an `#[inline(never)]` + `#[cold]` function removes a 6-byte `lea`
        // instruction vs `assert!(self.cursor != self.start, "Cannot pop all entries")`.
        // This reduces this function on x86_64 from 32 bytes to 26 bytes.
        // This function is commonly used, and we want it to be inlined, so every byte counts.
        // https://godbolt.org/z/5587z99rM
        #[inline(never)]
        #[cold]
        fn error() -> ! {
            panic!("Cannot pop all entries");
        }

        if self.cursor == self.start {
            error();
        }

        // SAFETY: Assertion above ensures stack has at least 2 entries
        unsafe { self.pop_unchecked() }
    }

    /// Pop value from stack, without checking that stack isn't empty.
    ///
    /// # SAFETY
    ///
    /// * Stack must have at least 2 entries, so that after pop, it still has at least 1.
    #[inline]
    pub unsafe fn pop_unchecked(&mut self) -> T {
        debug_assert!(self.cursor > self.start);

View on GitHub (pinned to 36ec0ef2ba)

Solutions

  1. Convert array syntax to object syntax with types: `props: { foo: String }`.
  2. For complex shapes use PropType with a constructor: `type: Object as PropType<MyShape>`.
  3. If a prop is deliberately untyped, suppress the rule on that line and note why in review.
  4. Prefer TS type-only defineProps so types come from the signature itself.

Example fix

// before
export default { props: ['foo', 'bar'] }

// after
export default { props: { foo: String, bar: Number } }
Defensive patterns

Strategy: validation

Validate before calling

// every prop must declare a type
function everyPropTyped(defs) {
  if (Array.isArray(defs)) {
    throw new Error('array-syntax props carry no types: ' + defs.join(','));
  }
  for (const [name, def] of Object.entries(defs)) {
    const t = typeof def === 'object' && def !== null ? def.type : def;
    if (!t) throw new Error(`prop '${name}' lacks a type`);
  }
}

Prevention

When it happens

Trigger: `props: ['foo', 'bar']`, `defineProps(['value'])`, or object props without a type (`props: { foo: {} }`) in a Vue component's default-export options object or equivalent declaration. The rule inspects object expressions, arrays, and call expressions (e.g. defineProps) within component definitions.

Common situations: Prototype-era components left with array props; props added quickly during feature work; migrations from very old Vue syntax where types were optional everywhere.

Related errors


AI-assisted analysis of oxc-project/oxc@36ec0ef2ba (2026-08-20). Data as JSON: /api/errors/b73b0da5537bc906. Report an issue: GitHub.