denoland/deno · error · TypeError
Failed to execute 'observe' on 'PerformanceObserver': 'entry
Error message
Failed to execute 'observe' on 'PerformanceObserver': 'entryTypes' must be an array.
What it means
When observe() is called with `entryTypes`, the Web Performance API requires it to be an array of strings. Deno checks Array.isArray immediately in ext/web/15_performance.js and throws a TypeError for anything else. After the check, unsupported type names are silently filtered against PerformanceObserver.supportedEntryTypes, which in Deno is ["mark", "measure"] — filtering all entries out just makes observe() a no-op (returns without observing).
Source
Thrown at ext/web/15_performance.js:526
const { entryTypes, type } = options;
if (entryTypes !== undefined && type !== undefined) {
throw new TypeError(
`${prefix}: Cannot specify both 'entryTypes' and 'type'.`,
);
}
if (entryTypes === undefined && type === undefined) {
throw new TypeError(
`${prefix}: Either 'entryTypes' or 'type' must be specified.`,
);
}
let types;
if (entryTypes !== undefined) {
if (!ArrayIsArray(entryTypes)) {
throw new TypeError(`${prefix}: 'entryTypes' must be an array.`);
}
types = ArrayPrototypeFilter(
entryTypes,
(t) =>
ArrayPrototypeIncludes(PerformanceObserver.supportedEntryTypes, t),
);
if (types.length === 0) {
return;
}
} else {
if (
!ArrayPrototypeIncludes(PerformanceObserver.supportedEntryTypes, type)
) {
return;
}
types = [type];
}
View on GitHub (pinned to 9ad36f7a2c)
Solutions
- Wrap the value in an array: observe({ entryTypes: ["mark"] }).
- If the value arrives as a string list, split it first: options.entryTypes.split(",").map((s) => s.trim()).
- Use the singular `type` option instead when observing exactly one entry type.
- Stick to "mark" and "measure" — other names are silently dropped in Deno.
Example fix
// before
observer.observe({ entryTypes: "mark" });
// after
observer.observe({ entryTypes: ["mark"] }); Defensive patterns
Strategy: type-guard
Validate before calling
if (!Array.isArray(opts.entryTypes)) {
opts.entryTypes = [String(opts.entryTypes)];
}
observer.observe(opts); Type guard
function isEntryTypesArray(v) {
return Array.isArray(v) && v.every((t) => typeof t === "string");
} Try / catch
try { observer.observe(opts); } catch (e) { if (e instanceof TypeError && e.message.includes("must be an array")) { opts.entryTypes = [opts.entryTypes]; observer.observe(opts); } else throw e; } Prevention
- Prefer the singular `type` option when observing one entry type.
- When accepting list-like config, normalize to an array at the boundary.
- Cross-check names against PerformanceObserver.supportedEntryTypes to avoid silent no-ops.
When it happens
Trigger: observe({ entryTypes: "mark" }) — a bare string instead of a one-element array; passing a Set, comma-separated list, or iterable; passing an object like { 0: "mark" } that is not a real Array.
Common situations: Single-type observation where the author forgot the brackets; receiving the list as a delimited string from config and forgetting to split it; mixing up the entryTypes form with the type form (type takes a string, entryTypes takes an array).
Understand the failure class
Background: "Wrong argument type", "must be a string", "expected Array or Prism::Scope": TypeError and ArgumentError when a library receives a value of the wrong type — this error's family across 28 libraries.
Related errors
- Failed to execute 'observe' on 'PerformanceObserver': Cannot
- Failed to execute 'observe' on 'PerformanceObserver': Either
- Options cannot be passed with "endMark"
- Cannot specify "start", "end", and "duration" together in op
- Failed to construct 'PerformanceObserver': The callback prov
AI-assisted analysis of denoland/deno@9ad36f7a2c (2026-08-20).
Data as JSON: /api/errors/8727251ba2a64927.
Report an issue: GitHub.