denoland/deno · error · TypeError

Failed to construct 'PerformanceObserver': The callback prov

Error message

Failed to construct 'PerformanceObserver': The callback provided as parameter 1 is not a function.

What it means

The PerformanceObserver constructor requires one argument that is a function (ext/web/15_performance.js:487-494). After webidl's required-arguments check passes, a callback that is not a function throws TypeError "Failed to construct 'PerformanceObserver': The callback provided as parameter 1 is not a function." The callback is stored and later invoked with PerformanceObserverEntryList snapshots.

Source

Thrown at ext/web/15_performance.js:491

const _entryTypes = Symbol("[[entryTypes]]");
const _buffer = Symbol("[[buffer]]");
const _scheduled = Symbol("[[scheduled]]");

class PerformanceObserver {
  static get supportedEntryTypes() {
    return ["mark", "measure"];
  }

  [_callback] = null;
  [_entryTypes] = [];
  [_buffer] = [];
  [_scheduled] = false;

  constructor(callback) {
    const prefix = "Failed to construct 'PerformanceObserver'";
    webidl.requiredArguments(arguments.length, 1, prefix);
    if (typeof callback !== "function") {
      throw new TypeError(
        `${prefix}: The callback provided as parameter 1 is not a function.`,
      );
    }
    this[webidl.brand] = webidl.brand;
    this[_callback] = callback;
  }

  observe(options = { __proto__: null }) {
    webidl.assertBranded(this, PerformanceObserverPrototype);
    const prefix = "Failed to execute 'observe' on 'PerformanceObserver'";

    if (options === undefined || options === null) {
      throw new TypeError(
        `${prefix}: 1 argument required, but only 0 present.`,
      );
    }

    const { entryTypes, type } = options;

View on GitHub (pinned to 9ad36f7a2c)

Solutions

  1. Pass a function: `new PerformanceObserver((list) => ...)`.
  2. Check the imported symbol exists and is a function before constructing.
  3. In tests, stub with `() => {}` rather than object literals.

Example fix

// before
new PerformanceObserver({ onmeasure: handle });

// after
new PerformanceObserver((list) => handle(list.getEntries()));
Defensive patterns

Strategy: type-guard

Validate before calling

if (typeof callback !== "function") {
  throw new TypeError("PerformanceObserver requires a function callback");
}
const obs = new PerformanceObserver(callback);

Type guard

const isObserverCallback = (v) => typeof v === "function";

Prevention

When it happens

Trigger: `new PerformanceObserver(null)`; `new PerformanceObserver('onMeasure')` (string instead of function); passing a value from a broken import that evaluated to undefined.

Common situations: Passing an options object instead of a callback; stubbing callbacks in tests with plain objects; wrong or missing imports yielding undefined; copy-paste from addEventListener-style APIs.

Related errors


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