{"record":{"id":"cd1e374ff15e1bbe","repo":"dotnet/aspnetcore","slug":"unable-to-focus-an-svg-element-that-does-not-have","errorCode":null,"errorMessage":"Unable to focus an SVG element that does not have a tabindex.","messagePattern":"Unable to focus an SVG element that does not have a tabindex\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/Components/Web.JS/src/DomWrapper.ts","lineNumber":18,"sourceCode":"// Licensed to the .NET Foundation under one or more agreements.\n// The .NET Foundation licenses this file to you under the MIT license.\n\nimport '@microsoft/dotnet-js-interop';\n\nexport const domFunctions = {\n  focus,\n  focusBySelector,\n};\n\nfunction focus(element: HTMLOrSVGElement, preventScroll: boolean): void {\n  if (element instanceof HTMLElement) {\n    element.focus({ preventScroll });\n  } else if (element instanceof SVGElement) {\n    if (element.hasAttribute('tabindex')) {\n      element.focus({ preventScroll });\n    } else {\n      throw new Error('Unable to focus an SVG element that does not have a tabindex.');\n    }\n  } else {\n    throw new Error('Unable to focus an invalid element.');\n  }\n}\n\nfunction focusBySelector(selector: string) {\n  const element = document.querySelector(selector) as HTMLElement;\n  if (element) {\n    // If no explicit tabindex is defined, mark it as programmatically-focusable.\n    // This does actually add a new HTML attribute, but it shouldn't interfere with\n    // diffing because diffing only deals with the attributes you have in your code.\n    if (!element.hasAttribute('tabindex')) {\n      element.tabIndex = -1;\n    }\n\n    element.focus({ preventScroll: true });\n  }","sourceCodeStart":1,"sourceCodeEnd":36,"githubUrl":"https://github.com/dotnet/aspnetcore/blob/294cab2f9b2e03af6b953820c7ab497c3c8b7ad9/src/Components/Web.JS/src/DomWrapper.ts#L1-L36","documentation":"Thrown by domFunctions.focus when the target is an SVGElement without a tabindex attribute. Unlike HTMLElement, SVG elements are not focusable by default; calling .focus() on one without an explicit tabindex has no effect and is almost always a bug, so Blazor refuses rather than silently no-op.","triggerScenarios":"A @focus directive or Blazor._internal.domFunctions.focus() call targeting an SVG element (e.g. <svg>, <rect>, <circle>, <path>) that has no tabindex attribute. Common when a component tries to programmatically focus an icon or vector graphic on validation error.","commonSituations":"Calling FocusAsync on an ElementReference pointing at an SVG; routing focus to an SVG icon used as a button without making it focusable; accessibility tooling that walks the DOM and focuses SVG nodes.","solutions":["Add tabindex=\"-1\" (or tabindex=\"0\") to the SVG element before focusing it.","Wrap the SVG in a focusable container (e.g. a <button>) and focus that instead.","Use focusBySelector with a selector that targets an HTMLElement ancestor.","Guard the call: if (element instanceof SVGElement && !element.hasAttribute('tabindex')) return;"],"exampleFix":"// before\n<svg #icon></svg>\nawait icon.FocusAsync(); // throws\n\n// after\n<svg #icon tabindex=\"-1\"></svg>\nawait icon.FocusAsync();","handlingStrategy":"type-guard","validationCode":"function focusIfFocusable(el: HTMLOrSVGElement | null, preventScroll = false) {\n  if (el instanceof SVGElement && !el.hasAttribute('tabindex')) return;\n  if (el instanceof HTMLElement || el instanceof SVGElement) {\n    el.focus({ preventScroll });\n  }\n}","typeGuard":"function isFocusable(el: HTMLOrSVGElement | null): el is HTMLElement | SVGElement {\n  if (el instanceof HTMLElement) return true;\n  if (el instanceof SVGElement) return el.hasAttribute('tabindex');\n  return false;\n}","tryCatchPattern":"try {\n  Blazor._internal.domFunctions.focus(svgEl, false);\n} catch (e) {\n  if (/does not have a tabindex/.test((e as Error).message)) {\n    svgEl.setAttribute('tabindex', '-1');\n    svgEl.focus({ preventScroll: false });\n  } else throw e;\n}","preventionTips":["Always add tabindex=\"-1\" to SVG elements you intend to focus programmatically.","Focus an HTMLElement button wrapping the SVG instead of the SVG itself.","Type-guard SVG elements and check for tabindex before focusing.","Use focusBySelector on a focusable ancestor selector."],"tags":["dom","focus","svg","accessibility"],"analyzedSha":"294cab2f9b2e03af6b953820c7ab497c3c8b7ad9","analyzedAt":"2026-08-06T20:08:02.189Z","schemaVersion":2},"datasetVersion":"2026-08-06T23:17:07.152Z"}