emberjs/ember.js · error · Error

createCache() must be passed a function as its first paramet

Error message

createCache() must be passed a function as its first parameter. Called with: ${String(fn)}

What it means

createCache() memoizes the result of a function so it can be validated for staleness later. In DEBUG builds the validator library verifies the first argument is actually a function before wrapping it; passing anything else (undefined, null, a string, a misnamed import) throws immediately instead of failing mysteriously later.

Source

Thrown at packages/@glimmer/validator/lib/tracking.ts:146

}

const FN = Symbol('FN');
const LAST_VALUE = Symbol('LAST_VALUE');
const TAG = Symbol('TAG');
const SNAPSHOT = Symbol('SNAPSHOT');
const DEBUG_LABEL = Symbol('DEBUG_LABEL');

interface InternalCache<T = unknown> {
  [FN]: (...args: unknown[]) => T;
  [LAST_VALUE]: T | undefined;
  [TAG]: Tag | undefined;
  [SNAPSHOT]: Revision;
  [DEBUG_LABEL]?: string | false | undefined;
}

export function createCache<T>(fn: () => T, debuggingLabel?: string | false): Cache<T> {
  if (DEBUG && !(typeof fn === 'function')) {
    throw new Error(
      `createCache() must be passed a function as its first parameter. Called with: ${String(fn)}`
    );
  }

  let cache: InternalCache<T> = {
    [FN]: fn,
    [LAST_VALUE]: undefined,
    [TAG]: undefined,
    [SNAPSHOT]: -1,
  };

  if (DEBUG) {
    cache[DEBUG_LABEL] = debuggingLabel;
  }

  return cache as unknown as Cache<T>;
}

View on GitHub (pinned to 26f97246a8)

Solutions

  1. Pass a function as the first argument: createCache(() => computeValue(), 'my label')
  2. Log the argument with console.log(String(fn)) at the call site to see what was actually passed
  3. Check for circular imports that leave the callback undefined at module-eval time
  4. Fix accidental invocation: createCache(fn) not createCache(fn())

Example fix

// before
const cache = createCache(config.loader());
// after
const cache = createCache(() => config.loader(), 'config-loader');
Defensive patterns

Strategy: validation

Validate before calling

if (typeof fn !== 'function') { throw new TypeError('createCache requires a function, got: ' + String(fn)); }
const cache = createCache(fn, 'myCache');

Type guard

function isCallable(v) { return typeof v === 'function'; }

Prevention

When it happens

Trigger: Calling createCache(x) where typeof x !== 'function' — e.g. an undefined callback due to a circular import, a forgotten arrow function (createCache(fn()) instead of createCache(fn)), or a null value from an optional dependency.

Common situations: Circular module imports resolving to undefined at call time; calling the function instead of passing it; typos in imports under tree-shaking/bundlers; Ember apps upgrading glimmer versions where a previously-optional argument became validated.

Related errors


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