squidfunk/mkdocs-material · error · ReferenceError

Missing element: expected "${selector}" to be present

Error message

Missing element: expected "${selector}" to be present

What it means

getElement() is the strict DOM lookup helper in Material for MkDocs' theme JavaScript. It wraps getOptionalElement() and throws a ReferenceError when the selector matches nothing in the document (or the given scope node). The library throws it because the caller requires the element to exist for the page to function, so failing fast is preferable to a silent null dereference later.

Source

Thrown at src/templates/assets/javascripts/browser/element/_/index.ts:77

 * @param selector - Query selector
 * @param node - Node of reference
 *
 * @returns Element
 */
export function getElement<T extends keyof HTMLElementTagNameMap>(
  selector: T, node?: ParentNode
): HTMLElementTagNameMap[T]

export function getElement<T extends HTMLElement>(
  selector: string, node?: ParentNode
): T

export function getElement<T extends HTMLElement>(
  selector: string, node: ParentNode = document
): T {
  const el = getOptionalElement<T>(selector, node)
  if (typeof el === "undefined")
    throw new ReferenceError(
      `Missing element: expected "${selector}" to be present`
    )

  /* Return element */
  return el
}

/* ------------------------------------------------------------------------- */

/**
 * Retrieve an optional element matching the query selector
 *
 * @template T - Element type
 *
 * @param selector - Query selector
 * @param node - Node of reference
 *
 * @returns Element or nothing

View on GitHub (pinned to e2136532f4)

Solutions

  1. Verify the selector exists in the current theme version's DOM; use document.querySelector in the console to check.
  2. If the element is truly optional, switch to getOptionalElement() and handle undefined.
  3. Pin the Material for MkDocs version to match the markup your script targets, and update selectors after upgrades.
  4. Delay the lookup until DOMContentLoaded / after the relevant component mounts, or pass the correct parent node as the second argument.

Example fix

// before
const content = getElement(".md-content__inner")

// after
const content = getOptionalElement(".md-content__inner")
if (typeof content === "undefined") return
Defensive patterns

Strategy: type-guard

Validate before calling

if (document.querySelector(selector) === null) {
  console.warn(`Element ${selector} not present; skipping setup`)
  return
}

Type guard

function hasElement<T extends HTMLElement>(selector: string, node: ParentNode = document): node is ParentNode & { querySelector(s: string): T } {
  return typeof node.querySelector<T>(selector) !== "undefined"
}

Try / catch

try {
  const el = getElement<T>(selector)
  // use el
} catch (e) {
  if (e instanceof ReferenceError && e.message.startsWith("Missing element")) {
    // fall back or bail out gracefully
  } else throw e
}

Prevention

When it happens

Trigger: Calling getElement<T>(selector) — directly or via getComponentElement, script, target, or inner — with a selector that matches no element, e.g. document.querySelector returns undefined because the element was removed, renamed, or never rendered.

Common situations: Custom overrides/patches reference theme internals whose markup changed between Material versions; a hook (like instant loading or tabs) runs before the element is rendered; a typo in a component selector like [data-md-component=...]; running scripts against a partial DOM (e.g. during header construction).

Related errors


AI-assisted analysis of squidfunk/mkdocs-material@e2136532f4 (2026-08-29). Data as JSON: /api/errors/b7694edd896093dd. Report an issue: GitHub.