mermaid-js/mermaid · error
Nodes and querySelector are both undefined
Error message
Nodes and querySelector are both undefined
What it means
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.
Source
Thrown at packages/mermaid/src/mermaid.ts:158
}
};
const runThrowsErrors = async function (
{ postRenderCallback, querySelector, nodes }: Omit<RunOptions, 'suppressErrors'> = {
querySelector: '.mermaid',
}
) {
const conf = mermaidAPI.getConfig();
log.debug(`${!postRenderCallback ? 'No ' : ''}Callback function found`);
let nodesToProcess: ArrayLike<HTMLElement>;
if (nodes) {
nodesToProcess = nodes;
} else if (querySelector) {
nodesToProcess = document.querySelectorAll(querySelector);
} else {
throw new Error('Nodes and querySelector are both undefined');
}
log.debug(`Found ${nodesToProcess.length} diagrams`);
if (conf?.startOnLoad !== undefined) {
log.debug('Start On Load: ' + conf?.startOnLoad);
mermaidAPI.updateSiteConfig({ startOnLoad: conf?.startOnLoad });
}
// generate the id of the diagram
const idGenerator = new utils.InitIDGenerator(conf.deterministicIds, conf.deterministicIDSeed);
let txt: string;
const errors: DetailedError[] = [];
// element is the current div with mermaid class
// eslint-disable-next-line unicorn/prefer-spread
for (const element of Array.from(nodesToProcess)) {
log.info('Rendering diagram: ' + element.id);View on GitHub (pinned to d93e9c88c0)
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.
Example fix
// before — explicit undefined overrides the default
const opts = someCond ? { nodes: els } : { querySelector: undefined };
await mermaid.run(opts);
// after — guarantee a selector
const opts = someCond ? { nodes: els } : { querySelector: '.mermaid' };
await mermaid.run(opts); Defensive patterns
Strategy: validation
Validate before calling
// Guarantee a node source before calling run
function runWith(opts = {}) {
if (!opts.nodes && !opts.querySelector) {
opts.querySelector = '.mermaid';
}
return mermaid.run(opts);
} Type guard
const hasNodeSource = (o): o is { nodes: ArrayLike<HTMLElement> } | { querySelector: string } =>
(o?.nodes != null && o.nodes.length >= 0) || typeof o?.querySelector === 'string' && o.querySelector.length > 0; Try / catch
try {
await mermaid.run(opts);
} catch (e) {
if (e instanceof Error && /Nodes and querySelector are both undefined/.test(e.message)) {
await mermaid.run({ ...opts, querySelector: '.mermaid' });
} else { throw e; }
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- No nodes found in layout data
- Layout data is required
- Configuration is required in layout data
- Nodes array is required in layout data
- Edges array is required in layout data
AI-assisted analysis of mermaid-js/mermaid@d93e9c88c0 (2026-08-12).
Data as JSON: /api/errors/ae2f4026250fc1ba.
Report an issue: GitHub.