mermaid-js/mermaid · error · Error
text requires set
Error message
text requires set
What it means
Thrown by the indentedTextTail production 'IDENTIFIER' (venn.jison:91) when an indented text value is reduced but yy.getCurrentSets() (vennDB.ts:92) returns undefined. currentSets is assigned only inside addSubsetData (vennDB.ts:26), which runs on 'set' and 'union' lines; an indented 'text <IDENTIFIER>' therefore needs a preceding set/union to attach to. With no current set in scope the text node would be orphaned, so the grammar rejects it. The thrown value is a plain Error.
Source
Thrown at packages/mermaid/src/diagrams/venn/parser/venn.jison:91
| SET identifier { yy.addSubsetData([$identifier], undefined, undefined); if (yy.setIndentMode) { yy.setIndentMode(true); } }
| SET identifier BRACKET_LABEL { yy.addSubsetData([$identifier], $BRACKET_LABEL, undefined); if (yy.setIndentMode) { yy.setIndentMode(true); } }
| SET identifier COLON NUMERIC { yy.addSubsetData([$identifier], undefined, parseFloat($NUMERIC)); if (yy.setIndentMode) { yy.setIndentMode(true); } }
| SET identifier BRACKET_LABEL COLON NUMERIC { yy.addSubsetData([$identifier], $BRACKET_LABEL, parseFloat($NUMERIC)); if (yy.setIndentMode) { yy.setIndentMode(true); } }
| UNION identifierList { if ($identifierList.length < 2) { throw new Error('union requires multiple identifiers'); } if (yy.validateUnionIdentifiers) { yy.validateUnionIdentifiers($identifierList); } yy.addSubsetData($identifierList, undefined, undefined); if (yy.setIndentMode) { yy.setIndentMode(true); } }
| UNION identifierList BRACKET_LABEL { if ($identifierList.length < 2) { throw new Error('union requires multiple identifiers'); } if (yy.validateUnionIdentifiers) { yy.validateUnionIdentifiers($identifierList); } yy.addSubsetData($identifierList, $BRACKET_LABEL, undefined); if (yy.setIndentMode) { yy.setIndentMode(true); } }
| UNION identifierList COLON NUMERIC { if ($identifierList.length < 2) { throw new Error('union requires multiple identifiers'); } if (yy.validateUnionIdentifiers) { yy.validateUnionIdentifiers($identifierList); } yy.addSubsetData($identifierList, undefined, parseFloat($NUMERIC)); if (yy.setIndentMode) { yy.setIndentMode(true); } }
| UNION identifierList BRACKET_LABEL COLON NUMERIC { if ($identifierList.length < 2) { throw new Error('union requires multiple identifiers'); } if (yy.validateUnionIdentifiers) { yy.validateUnionIdentifiers($identifierList); } yy.addSubsetData($identifierList, $BRACKET_LABEL, parseFloat($NUMERIC)); if (yy.setIndentMode) { yy.setIndentMode(true); } }
| TEXT identifierList IDENTIFIER { yy.addTextData($identifierList, $IDENTIFIER, undefined); }
| TEXT identifierList STRING { yy.addTextData($identifierList, $STRING, undefined); }
| TEXT identifierList NUMERIC { yy.addTextData($identifierList, $NUMERIC, undefined); }
| TEXT identifierList IDENTIFIER BRACKET_LABEL { yy.addTextData($identifierList, $IDENTIFIER, $BRACKET_LABEL); }
| TEXT identifierList STRING BRACKET_LABEL { yy.addTextData($identifierList, $STRING, $BRACKET_LABEL); }
| INDENT_TEXT indentedTextTail { $$ = $2; }
| STYLE identifierList stylesOpt { yy.addStyleData($identifierList, $stylesOpt); }
;
indentedTextTail
: IDENTIFIER { var cs = yy.getCurrentSets(); if (!cs) throw new Error('text requires set'); yy.addTextData(cs, $IDENTIFIER, undefined); }
| STRING { var cs = yy.getCurrentSets(); if (!cs) throw new Error('text requires set'); yy.addTextData(cs, $STRING, undefined); }
| NUMERIC { var cs = yy.getCurrentSets(); if (!cs) throw new Error('text requires set'); yy.addTextData(cs, $NUMERIC, undefined); }
| IDENTIFIER BRACKET_LABEL { var cs = yy.getCurrentSets(); if (!cs) throw new Error('text requires set'); yy.addTextData(cs, $IDENTIFIER, $BRACKET_LABEL); }
| STRING BRACKET_LABEL { var cs = yy.getCurrentSets(); if (!cs) throw new Error('text requires set'); yy.addTextData(cs, $STRING, $BRACKET_LABEL); }
;
stylesOpt
: styleField { $$ = [$styleField] }
| stylesOpt COMMA styleField { $$ = [...$stylesOpt, $styleField] }
;
styleField
: IDENTIFIER COLON styleValue { $$ = [$1, $3] }
;
styleValue
: STRING { $$ = $1; }
| valueTokens { $$ = $valueTokens.join(' '); }View on GitHub (pinned to d93e9c88c0)
Solutions
- Ensure a 'set' or 'union' statement precedes each indented 'text' group, since addSubsetData is what populates currentSets.
- Use the inline form 'text identifierList value' (venn.jison:81-85), which carries its own explicit set list and does not depend on currentSets.
- Verify the text line is indented under the intended set/union and that no clear/reset happened between them.
Example fix
// before
venn-beta
text A1
// after
venn-beta
set A
text A1 Defensive patterns
Strategy: validation
Validate before calling
// Ensure every indented 'text' has a preceding set/union in scope.
function validateIndentedText(src) {
let hasCurrentSet = false;
for (const raw of src.split('\n')) {
if (/^\s*(set|union)\b/i.test(raw)) { hasCurrentSet = true; continue; }
if (/^\s+text\b/i.test(raw) && !hasCurrentSet) {
throw new Error('text requires a preceding set/union: ' + raw.trim());
}
}
} Type guard
function isTextRequiresSetError(e) { return e instanceof Error && /text requires set/.test(e.message); } Try / catch
try {
venn.parse(src);
} catch (e) {
if (e instanceof Error && /text requires set/.test(e.message)) {
// indented text needs a parent set/union; suggest the inline 'text <sets> <value>' form
} else throw e;
} Prevention
- Always declare the parent 'set'/'union' before its indented 'text' children.
- If you cannot guarantee ordering, use the inline form 'text identifierList value' which is order-independent.
- Keep text lines indented under their set so the indent-mode lexer attaches them correctly.
- Run the indented-text validator above on generated venn sources.
When it happens
Trigger: A venn-beta diagram in indent mode where an indented 'text <IDENTIFIER>' line (matched by the bol/INDENT_TEXT lexer rules at venn.jison:11-17) appears before any 'set' or 'union' line, so currentSets is still undefined when indentedTextTail reduces.
Common situations: Placing a text block at the top of the diagram before any set; reordering lines so a text line ends up above its set; indent mode remaining enabled across a diagram boundary after clear(); copy-paste that drops the leading set line.
Related errors
- union requires multiple identifiers
- Error: State name must be a single word. Found: "${yytext.tr
- Parsing failed: ${lexerErrors} ${parserErrors}
- Diagram ${type} not found.
- No diagram type detected matching given configuration for te
AI-assisted analysis of mermaid-js/mermaid@d93e9c88c0 (2026-08-12).
Data as JSON: /api/errors/57d81eb576803e90.
Report an issue: GitHub.