{"record":{"id":"79f33b1634ca8a31","repo":"usablica/intro.js","slug":"element-with-selector-selector-not-found","errorCode":null,"errorMessage":"Element with selector ${selector} not found","messagePattern":"Element with selector (.+?) not found","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/util/queryElement.ts","lineNumber":29,"sourceCode":"): NodeListOf<HTMLElement> => {\n  return (container ?? document).querySelectorAll(selector);\n};\n\nexport const queryElementsByClassName = (\n  className: string,\n  container?: HTMLElement | null\n): NodeListOf<HTMLElement> => {\n  return queryElements(`.${className}`, container);\n};\n\nexport const getElement = (\n  selector: string,\n  container?: HTMLElement | null\n) => {\n  const element = queryElement(selector, container);\n\n  if (!element) {\n    throw new Error(`Element with selector ${selector} not found`);\n  }\n\n  return element;\n};\n","sourceCodeStart":11,"sourceCodeEnd":34,"githubUrl":"https://github.com/usablica/intro.js/blob/e5517e6a24e0530f87885af9fb2a69bafd1d4a6b/src/util/queryElement.ts#L11-L34","documentation":"getElement() resolves a CSS selector via queryElement() and throws when nothing matches in the document (or the optional container). Unlike queryElement(), which returns null, getElement() is the strict variant asserting the element must exist, used to initialize tours/hints against required DOM nodes.","triggerScenarios":"Calling introJs.tour('#step-1') or any API that runs getElement() with a selector that matches no element, a misspelled selector, an element inside a container passed as null, or an element not yet rendered when the call executes.","commonSituations":"Calling intro before the DOM has rendered (scripts in <head>, SPA route mount race, dynamic content not yet injected); typo in class/id (missing dot or hash); element only exists conditionally; SSR where document has no such element; scoping to a container that doesn't contain the node.","solutions":["Call the tour/hint setup after the DOM element exists (on mount / DOMContentLoaded / after render).","Verify the selector matches in DevTools (document.querySelector(selector) !== null) — check for missing '.', '#', typos.","Pass the correct container argument if the element lives inside a specific container.","If the element is optional, use queryElement() (returns null) instead of getElement()."],"exampleFix":"// before\nintroJs.tour('#save-button'); // may run before render\n// after\ndocument.addEventListener('DOMContentLoaded', () => {\n  if (document.querySelector('#save-button')) introJs.tour('#save-button');\n});","handlingStrategy":"validation","validationCode":"const el = document.querySelector('#save-button');\nif (!el) throw new Error('#save-button missing — aborting tour setup');\nintroJs.tour('#save-button');","typeGuard":"function elementExists(selector: string, root: ParentNode = document): boolean {\n  return root.querySelector(selector) !== null;\n}","tryCatchPattern":"try {\n  introJs.tour('#save-button');\n} catch (e) {\n  if (String(e.message).includes('not found')) {\n    console.warn('Tour target missing, skipping intro:', e.message);\n  } else throw e;\n}","preventionTips":["Initialize tours after DOM render (DOMContentLoaded, framework mount hooks).","Validate selectors with document.querySelector before registering.","Double-check '#'/ '.' prefixes and spelling of ids/classes.","For optional elements, use queryElement() which returns null instead of throwing.","In SPAs, re-run setup when route/dynamic content changes."],"tags":["dom","selector","not-found"],"backgroundTag":"element-not-found","analyzedSha":"e5517e6a24e0530f87885af9fb2a69bafd1d4a6b","analyzedAt":"2026-08-31T22:12:26.007Z","schemaVersion":2},"datasetVersion":"2026-08-31T22:30:34.772Z"}