{"record":{"id":"ae2f4026250fc1ba","repo":"mermaid-js/mermaid","slug":"nodes-and-queryselector-are-both-undefined","errorCode":null,"errorMessage":"Nodes and querySelector are both undefined","messagePattern":"Nodes and querySelector are both undefined","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/mermaid/src/mermaid.ts","lineNumber":158,"sourceCode":"  }\n};\n\nconst runThrowsErrors = async function (\n  { postRenderCallback, querySelector, nodes }: Omit<RunOptions, 'suppressErrors'> = {\n    querySelector: '.mermaid',\n  }\n) {\n  const conf = mermaidAPI.getConfig();\n\n  log.debug(`${!postRenderCallback ? 'No ' : ''}Callback function found`);\n\n  let nodesToProcess: ArrayLike<HTMLElement>;\n  if (nodes) {\n    nodesToProcess = nodes;\n  } else if (querySelector) {\n    nodesToProcess = document.querySelectorAll(querySelector);\n  } else {\n    throw new Error('Nodes and querySelector are both undefined');\n  }\n\n  log.debug(`Found ${nodesToProcess.length} diagrams`);\n  if (conf?.startOnLoad !== undefined) {\n    log.debug('Start On Load: ' + conf?.startOnLoad);\n    mermaidAPI.updateSiteConfig({ startOnLoad: conf?.startOnLoad });\n  }\n\n  // generate the id of the diagram\n  const idGenerator = new utils.InitIDGenerator(conf.deterministicIds, conf.deterministicIDSeed);\n\n  let txt: string;\n  const errors: DetailedError[] = [];\n\n  // element is the current div with mermaid class\n  // eslint-disable-next-line unicorn/prefer-spread\n  for (const element of Array.from(nodesToProcess)) {\n    log.info('Rendering diagram: ' + element.id);","sourceCodeStart":140,"sourceCodeEnd":176,"githubUrl":"https://github.com/mermaid-js/mermaid/blob/d93e9c88c01a599c062ee6a3f1462e3558ac6b90/packages/mermaid/src/mermaid.ts#L140-L176","documentation":"runThrowsErrors() (the core of mermaid.run) needs a source of elements: either an explicit `nodes` array or a CSS `querySelector` matched against the document. If both are undefined it cannot find any diagrams and throws immediately. The public run() default is `querySelector: '.mermaid'`, so reaching this means the caller explicitly passed options that overrode the default with undefined.","triggerScenarios":"Calling mermaid.run({}) or mermaid.run({ nodes: undefined, querySelector: undefined }) so the destructured options lose the '.mermaid' default; passing a falsy querySelector assuming a default still applies; calling runThrowsErrors() directly with no args in a non-DOM context.","commonSituations":"Constructing options dynamically and accidentally setting querySelector to undefined/null/empty; SSR or test environments where document is absent and callers pass nothing; refactors that build the options object conditionally and omit the selector.","solutions":["Pass a selector: mermaid.run({ querySelector: '.mermaid' }).","Or pass explicit nodes: mermaid.run({ nodes: document.querySelectorAll('.mermaid') }).","When building options conditionally, fall back to '.mermaid' if your value is falsy.","Avoid calling runThrowsErrors directly; use the public run() which defaults the selector."],"exampleFix":"// before — explicit undefined overrides the default\nconst opts = someCond ? { nodes: els } : { querySelector: undefined };\nawait mermaid.run(opts);\n\n// after — guarantee a selector\nconst opts = someCond ? { nodes: els } : { querySelector: '.mermaid' };\nawait mermaid.run(opts);","handlingStrategy":"validation","validationCode":"// Guarantee a node source before calling run\nfunction runWith(opts = {}) {\n  if (!opts.nodes && !opts.querySelector) {\n    opts.querySelector = '.mermaid';\n  }\n  return mermaid.run(opts);\n}","typeGuard":"const hasNodeSource = (o): o is { nodes: ArrayLike<HTMLElement> } | { querySelector: string } =>\n  (o?.nodes != null && o.nodes.length >= 0) || typeof o?.querySelector === 'string' && o.querySelector.length > 0;","tryCatchPattern":"try {\n  await mermaid.run(opts);\n} catch (e) {\n  if (e instanceof Error && /Nodes and querySelector are both undefined/.test(e.message)) {\n    await mermaid.run({ ...opts, querySelector: '.mermaid' });\n  } else { throw e; }\n}","preventionTips":["Always pass at least one of nodes or querySelector to mermaid.run.","Default querySelector to '.mermaid' when building options conditionally.","Avoid calling the internal runThrowsErrors directly."],"tags":["mermaid-api","run","options","dom","validation"],"backgroundTag":null,"analyzedSha":"d93e9c88c01a599c062ee6a3f1462e3558ac6b90","analyzedAt":"2026-08-12T06:23:11.304Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}