Stirling-Tools/Stirling-PDF · warning · Error
Expected primary
Error message
Expected primary
What it means
Thrown by parsePrimary when the current token is not any recognizable primary element: not '(', not a keyword (even/odd), not a progression (kn+c), and not a leading number. The parser has exhausted all primary alternatives, so it cannot proceed. As with other parser errors, only surfaces in strict mode; otherwise CSV fallback applies.
Source
Thrown at frontend/editor/src/core/utils/bulkselection/parseSelection.ts:237
return this.buildProgression(progression.k, progression.c);
}
// Number or Range
const num = this.tryReadNumber();
if (num !== null) {
this.skipWs();
if (this.peek("-")) {
// Range
this.consume(1);
this.skipWs();
const end = this.readRequiredNumber();
return this.buildRange(num, end);
}
return this.buildSingleton(num);
}
// If nothing matched, error
throw new Error("Expected primary");
}
private buildSingleton(n: number): Set<number> {
const set = new Set<number>();
if (n >= 1 && n <= this.max) set.add(n);
return set;
}
private buildRange(a: number, b: number): Set<number> {
const set = new Set<number>();
let start = a,
end = b;
if (!Number.isFinite(start) || !Number.isFinite(end)) return set;
if (start > end) [start, end] = [end, start];
start = Math.max(1, start);
end = Math.min(this.max, end);
for (let i = start; i <= end; i++) set.add(i);
return set;View on GitHub (pinned to 9ef20dcab8)
Solutions
- Ensure each operator ('&', '|', ',', '-') is surrounded by valid primaries, not by another operator.
- Start the expression with a number, keyword (even/odd), '(', or '!'.
- Remove stray symbols; the grammar accepts only the documented operators.
- Use the diagnostics warning (non-strict) to locate the malformed token before enabling strict rejection.
Example fix
// before
parseSelectionWithDiagnostics('1-5 & & 7', max, { strict: true })
// after
parseSelectionWithDiagnostics('1-5 & 7', max, { strict: true }) Defensive patterns
Strategy: validation
Validate before calling
function hasNoDoubledOperators(input: string): boolean {
return !/[&|]\s*[&|]/.test(input) && !/^[&|]/.test(input);
}
if (!hasNoDoubledOperators(input)) {
showUser('Remove doubled or leading operators.');
} Type guard
function startsWithValidPrimary(input: string): boolean {
const trimmed = input.trimStart();
return /^[\d(!]|^(even|odd)\b/i.test(trimmed);
} Try / catch
try {
const { pages } = parseSelectionWithDiagnostics(input, maxPages, { strict: true });
} catch (e) {
if (e instanceof Error && e.message === 'Expected primary') {
showUser('Each part of the expression must be a number, range, keyword, or group.');
} else { throw e; }
} Prevention
- Avoid doubling operators ('&&', '||'); use single '&' or '|'.
- Start the expression with a number, '(', '!', or even/odd.
- Use non-strict mode to get a fallback and warning rather than an exception.
- Provide inline examples of valid syntax.
When it happens
Trigger: Input like '& 5' (operator with no left operand at primary position), '1-5 & & 7' (double operator), '*5' (bare multiplication), or an expression starting with a symbol that is not '(' or '!'. Also a leading '&', '|', or '-' where a primary is expected after an operator.
Common situations: User typed a doubled operator, started the expression with an operator, or used a symbol not in the grammar at a position requiring a value. Pasted text containing special characters. Non-strict mode swallows this into the CSV fallback.
Related errors
- Expected )
- Unexpected trailing input
- Expected number
- No team resolved yet
- No automation configuration provided
AI-assisted analysis of Stirling-Tools/Stirling-PDF@9ef20dcab8 (2026-08-13).
Data as JSON: /api/errors/0d16a11555fbab51.
Report an issue: GitHub.