denoland/deno · error · ERR_INVALID_ARG_TYPE

ERR_INVALID_ARG_TYPE

ERR_INVALID_ARG_TYPE

Error message

The "callback" argument must be an instance of Function. Received ${received}

What it means

`new PerformanceObserver(callback)` requires a function as its only argument. The perf_hooks polyfill throws ERR_INVALID_ARG_TYPE for anything else, including a missing argument. The web PerformanceObserver it extends has the same requirement.

Source

Thrown at ext/node/polyfills/perf_hooks.js:102

    getEntriesByName(name, type) {
      return ArrayPrototypeFilter(
        entries,
        (e) => e.name === name && (type === undefined || e.entryType === type),
      );
    },
  };
}

// Node-compatible PerformanceObserver that throws proper Node.js errors
class PerformanceObserver extends WebPerformanceObserver {
  [_nodeTypes] = [];
  [_nodeBuffer] = [];
  [_nodeScheduled] = false;
  [_nodeCallback] = null;

  constructor(callback) {
    if (typeof callback !== "function") {
      throw new ERR_INVALID_ARG_TYPE("callback", "Function", callback);
    }
    super(callback);
    this[_nodeCallback] = callback;
  }

  static get supportedEntryTypes() {
    return [
      ...new SafeArrayIterator(WebPerformanceObserver.supportedEntryTypes),
      ...new SafeArrayIterator(NODE_ENTRY_TYPES),
    ];
  }

  observe(options) {
    if (typeof options !== "object" || options === null) {
      throw new ERR_INVALID_ARG_TYPE("options", "Object", options);
    }
    if (
      options.entryTypes !== undefined && !ArrayIsArray(options.entryTypes)

View on GitHub (pinned to 9ad36f7a2c)

Solutions

  1. Pass a function: `new PerformanceObserver((list) => { ... })`.
  2. For class methods, pass an arrow that binds this: `(list) => this.onEntries(list)`.
  3. Check the import when the value is undefined — verify named vs default export.

Example fix

// before
new PerformanceObserver();

// after
new PerformanceObserver((list) => {
  for (const entry of list.getEntries()) console.log(entry.name);
});
Defensive patterns

Strategy: type-guard

Validate before calling

if (typeof callback !== 'function') {
  throw new Error('PerformanceObserver needs a callback function');
}
const obs = new PerformanceObserver(callback);

Type guard

function isObserverCallback(v: unknown): v is (list: unknown) => void {
  return typeof v === 'function';
}

Prevention

When it happens

Trigger: `new PerformanceObserver()` with no argument; passing an options object like `{ onEntry: fn }`; a callback variable that is undefined because the import binding did not exist; passing a string name of a function.

Common situations: Named vs default export mixups that leave an imported symbol undefined. Wrapper APIs that accept a config object where Node expects a bare function. Copy-paste from observer examples in other languages.

Understand the failure class

Background: Invalid argument type errors: "must be of type string", "expected X, got Y", and ERR_INVALID_ARG_TYPE explained — this error's family across 15 libraries.

Related errors


AI-assisted analysis of denoland/deno@9ad36f7a2c (2026-08-20). Data as JSON: /api/errors/5bc13c36208d3efe. Report an issue: GitHub.