Automattic/harper · error · TypeError
Expected a DOM Element
Error message
Expected a DOM Element
What it means
lint-framework's Highlights.isContainingBlock computes computed styles to detect containing blocks; it begins by asserting the argument is a DOM Element and throws TypeError('Expected a DOM Element') otherwise. This is called from getInitialContainingRect while mapping lint spans to on-screen rectangles, so it fires when highlight bookkeeping feeds a non-Element into containing-block resolution.
Source
Thrown at packages/lint-framework/src/lint/Highlights.ts:287
if (isContainingBlock(node)) {
return node.getBoundingClientRect();
}
node = node.parentElement;
}
return null;
}
/**
* Determines whether a given element would form the containing block
* for a descendant with `position: fixed`, based on CSS transforms,
* filters, containment, container queries, will-change, and
* content-visibility.
*
* Logs the element and the precise reason it qualifies.
*/
function isContainingBlock(el: Element): boolean {
if (!(el instanceof Element)) {
throw new TypeError('Expected a DOM Element');
}
const style = window.getComputedStyle(el);
const filter = style.getPropertyValue('filter');
if (filter !== 'none') {
return true;
}
const backdrop = style.getPropertyValue('backdrop-filter');
if (backdrop !== 'none') {
return true;
}
const transform = style.getPropertyValue('transform');
if (transform !== 'none') {
return true;
}View on GitHub (pinned to 5fe7d5ab76)
Solutions
- Guard the call site: skip isContainingBlock when the candidate is null or its nodeType is not 1 (Node.ELEMENT_NODE).
- Update lint-framework to a version that handles a missing parent before calling isContainingBlock.
- Check that the element you highlight inside is attached to the document and is an Element (nodeType 1).
- In tests, provide a realistic DOM (jsdom with parent traversal) or mock getInitialContainingRect.
Example fix
// before (SSR)
const highlights = new Highlights(editorEl); // runs during server render
// after
import { browser } from '$app/environment';
if (browser) {
const highlights = new Highlights(editorEl);
} Defensive patterns
Strategy: type-guard
Validate before calling
if (typeof window === 'undefined') {
throw new Error('Highlights requires a browser DOM environment');
} Type guard
function isElement(v: unknown): v is Element {
return typeof Element !== 'undefined' && v instanceof Element;
} Try / catch
try {
const rect = highlights.getInitialContainingRect(lint);
} catch (e) {
if (e instanceof TypeError && e.message === 'Expected a DOM Element') {
console.error('Highlighter ran outside a browser DOM; skip highlight setup.');
}
throw e;
} Prevention
- Only initialize the highlight framework in browser contexts (guard against SSR)
- Ensure the highlight target is attached and is an Element (nodeType 1)
- In tests, use a DOM environment with full parent traversal or mock rect lookup
When it happens
Trigger: Passing a non-Element into isContainingBlock while a DOM is present: el.parentElement returning null as the upward walk reaches the document root, a text or comment node arriving from a shadow-DOM or custom rendering path, or a detached placeholder swapped in mid-highlight. A DOM is required for this error to be reachable at all — the check is `el instanceof Element`, so an environment with no global Element (bare Node, SSR without DOM shims) raises ReferenceError: Element is not defined on that same line instead.
Common situations: Frameworks replacing nodes mid-highlight so parentElement is null by the time the lookup runs; shadow-DOM or custom renderers handing the highlighter a text node; jsdom setups that define Element but not the parent chain the walk expects.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- Expected binary to be a string of url but got ${typeof binar
- HTMLElement not added.
- TextFieldRange expects an HTMLTextAreaElement or HTMLInputEl
AI-assisted analysis of Automattic/harper@5fe7d5ab76 (2026-09-06).
Data as JSON: /api/errors/57c27067ed60784e.
Report an issue: GitHub.