tobi/qmd · error · Error
Line ${line.number}: only one intent: line is allowed per be
Error message
Line ${line.number}: only one intent: line is allowed per benchmark query. What it means
Thrown by parseStructuredQuery in src/bench/bench.ts when a benchmark fixture query document contains more than one 'intent:' line. Each multi-line query in a bench fixture may carry at most a single intent annotation; the second occurrence aborts parsing.
Source
Thrown at src/bench/bench.ts:62
};
function parseStructuredQuery(query: string): ParsedStructuredQuery | undefined {
const lines = query.split("\n").map((line, idx) => ({
trimmed: line.trim(),
number: idx + 1,
})).filter(line => line.trimmed.length > 0);
if (lines.length === 0) return undefined;
const prefixRe = /^(lex|vec|hyde):\s*/i;
const intentRe = /^intent:\s*/i;
const searches: ExpandedQuery[] = [];
let intent: string | undefined;
for (const line of lines) {
if (intentRe.test(line.trimmed)) {
if (intent !== undefined) {
throw new Error(`Line ${line.number}: only one intent: line is allowed per benchmark query.`);
}
intent = line.trimmed.replace(intentRe, "").trim();
if (!intent) {
throw new Error(`Line ${line.number}: intent: must include text.`);
}
continue;
}
const match = line.trimmed.match(prefixRe);
if (match) {
const type = match[1]!.toLowerCase() as "lex" | "vec" | "hyde";
const text = line.trimmed.slice(match[0].length).trim();
if (!text) {
throw new Error(`Line ${line.number} (${type}:) must include text.`);
}
searches.push({ type, query: text, line: line.number });
continue;
}View on GitHub (pinned to dbfd0b4736)
Solutions
- Delete the duplicate intent: line so exactly one remains per query document
- Merge the two intent descriptions into a single intent: line
- Run qmd bench with a small fixture to validate syntax before the full run
Example fix
// before "lex: install steps\nintent: setup help\nintent: installation docs" // after "lex: install steps\nintent: setup and installation docs"
Defensive patterns
Strategy: validation
Validate before calling
const intentCount = (doc.match(/^\s*intent:/gm) || []).length;
if (intentCount > 1) throw new RangeError(`fixture query has ${intentCount} intent: lines; max 1`); Type guard
const hasSingleIntent = (doc: string) => (doc.match(/^\s*intent:/gm) || []).length <= 1;
Prevention
- Validate fixture query documents with a regex count of intent: lines before qmd bench
- Keep fixtures in version control and lint them in CI
When it happens
Trigger: A fixture JSON query whose document string has two lines starting with 'intent:', e.g. 'intent: find setup docs\nintent: find config docs\nlex: install'. Passed to runBenchmark via the fixture's queries array.
Common situations: Copy-pasting an intent line while editing bench fixtures; merging two query documents into one; appending notes that accidentally use the intent: prefix.
Related errors
- Line ${line.number}: intent: must include text.
- Line ${line.number} (${type}:) must include text.
- Line ${line.number} is missing a lex:/vec:/hyde:/intent: pre
- intent: cannot appear alone. Add at least one lex:, vec:, or
- Invalid fixture: missing 'queries' array
AI-assisted analysis of tobi/qmd@dbfd0b4736 (2026-08-28).
Data as JSON: /api/errors/f514c3094dbde2fb.
Report an issue: GitHub.