emberjs/ember.js · error · TypeError

Reduce of empty array with no initial value

Error message

Reduce of empty array with no initial value

What it means

EmberArray#reduce mirrors native Array.reduce semantics: without an initial value it uses the first element as the seed. If the enumerable is empty and no initialValue argument was passed, there is no seed value, so it throws a TypeError.

Source

Thrown at packages/@ember/array/index.ts:1342

    let callback = iter(...arguments);
    return any(this, callback);
  },

  // FIXME: When called without initialValue, behavior does not match native behavior
  reduce<T, V>(
    this: EmberArray<T>,
    callback: (summation: V, current: T, index: number, arr: EmberArray<T>) => V,
    initialValue?: V
  ) {
    assert('`reduce` expects a function as first argument.', typeof callback === 'function');

    let hasInitialValue = arguments.length > 1;
    let ret: any = initialValue;
    let startIndex = 0;

    if (!hasInitialValue) {
      if (this.length === 0) {
        throw new TypeError('Reduce of empty array with no initial value');
      }
      ret = this.objectAt(0);
      startIndex = 1;
    }

    for (let i = startIndex; i < this.length; i++) {
      let item = this.objectAt(i) as T;
      ret = callback(ret, item, i, this);
    }

    return ret;
  },

  invoke<T>(this: EmberArray<T>, methodName: string, ...args: unknown[]) {
    let ret = A();

    // SAFETY: This is not entirely safe and the code will not work with Ember proxies
    this.forEach((item: T) => ret.push((item as any)[methodName]?.(...args)));

View on GitHub (pinned to 26f97246a8)

Solutions

  1. Pass an initial value: arr.reduce(fn, 0)
  2. Check arr.length > 0 before reducing
  3. Provide a default via computed/fallback logic

Example fix

// before
let total = items.reduce((sum, item) => sum + item.price, );
// after
let total = items.reduce((sum, item) => sum + item.price, 0);
Defensive patterns

Strategy: validation

Validate before calling

if (arr.length === 0) return 0; let total = arr.reduce((s, x) => s + x, 0);

Type guard

function isNonEmptyReducible(arr) { return Array.isArray(arr) && arr.length > 0; }

Try / catch

try { return arr.reduce(fn); } catch (e) { if (e instanceof TypeError && /no initial value/.test(e.message)) return undefined; throw e; }

Prevention

When it happens

Trigger: Calling someArray.reduce(fn) with exactly one argument on an empty Ember array (this.length === 0 and arguments.length <= 1 in the reduce implementation at packages/@ember/array/index.ts).

Common situations: Aggregating filtered results that can legitimately be empty (sums of filtered records, computed properties over empty lists).

Related errors


AI-assisted analysis of emberjs/ember.js@26f97246a8 (2026-09-01). Data as JSON: /api/errors/85b08430265aec90. Report an issue: GitHub.