dotnet/aspnetcore · error · Error

Unable to focus an invalid element.

Error message

Unable to focus an invalid element.

What it means

Thrown by domFunctions.focus when the target is neither an HTMLElement nor an SVGElement (it falls through both instanceof checks). This indicates the caller passed something invalid (null, a non-element node, or an object whose prototype chain does not include HTMLElement/SVGElement), and the framework cannot focus it.

Source

Thrown at src/Components/Web.JS/src/DomWrapper.ts:21

import '@microsoft/dotnet-js-interop';

export const domFunctions = {
  focus,
  focusBySelector,
};

function focus(element: HTMLOrSVGElement, preventScroll: boolean): void {
  if (element instanceof HTMLElement) {
    element.focus({ preventScroll });
  } else if (element instanceof SVGElement) {
    if (element.hasAttribute('tabindex')) {
      element.focus({ preventScroll });
    } else {
      throw new Error('Unable to focus an SVG element that does not have a tabindex.');
    }
  } else {
    throw new Error('Unable to focus an invalid element.');
  }
}

function focusBySelector(selector: string) {
  const element = document.querySelector(selector) as HTMLElement;
  if (element) {
    // If no explicit tabindex is defined, mark it as programmatically-focusable.
    // This does actually add a new HTML attribute, but it shouldn't interfere with
    // diffing because diffing only deals with the attributes you have in your code.
    if (!element.hasAttribute('tabindex')) {
      element.tabIndex = -1;
    }

    element.focus({ preventScroll: true });
  }
}

View on GitHub (pinned to 294cab2f9b)

Solutions

  1. Null-check the element before focusing: if (element instanceof HTMLElement || element instanceof SVGElement) focus(element).
  2. Ensure the ElementReference is attached to a real rendered element (not null) before calling FocusAsync.
  3. If the element comes from another iframe/Realm, use duck-typing (typeof element.focus === 'function') instead of instanceof, or pass the element via its own Realm's API.
  4. Focus an HTMLElement ancestor instead of the invalid target.

Example fix

// before
const el = document.querySelector('#maybe-missing');
Blazor._internal.domFunctions.focus(el, false); // el is null -> throws

// after
const el = document.querySelector('#maybe-missing');
if (el instanceof HTMLElement || el instanceof SVGElement) {
  Blazor._internal.domFunctions.focus(el, false);
}
Defensive patterns

Strategy: type-guard

Validate before calling

function focusSafe(el: HTMLOrSVGElement | null, preventScroll = false) {
  if (el && (el instanceof HTMLElement || el instanceof SVGElement)) {
    el.focus({ preventScroll });
  }
}

Type guard

function isFocusableElement(el: unknown): el is HTMLElement | SVGElement {
  return el instanceof HTMLElement || el instanceof SVGElement;
}

// Cross-Realm-safe variant:
function isFocusableLike(el: unknown): boolean {
  return !!el && typeof (el as any).focus === 'function';
}

Try / catch

try {
  Blazor._internal.domFunctions.focus(target, false);
} catch (e) {
  if (/Unable to focus an invalid element/.test((e as Error).message)) {
    console.warn('Skipping focus on invalid element', target);
  } else throw e;
}

Prevention

When it happens

Trigger: Passing null/undefined, a Document, a Text node, a detached element whose prototype got mangled (e.g. from another iframe/Realm where instanceof fails), or a polyfilled element to Blazor._internal.domFunctions.focus / FocusAsync.

Common situations: ElementReference resolving to null after a re-render; cross-iframe DOM nodes where instanceof HTMLElement fails across Realms; passing a wrapped/proxied element from a third-party library; calling focus on a DocumentFragment or comment node.

Related errors


AI-assisted analysis of dotnet/aspnetcore@294cab2f9b (2026-08-06). Data as JSON: /api/errors/2a04c17080f08d77. Report an issue: GitHub.