can1357/oh-my-pi · error · OmpTypeError
unexpected end of definition "${this.#src}"
Error message
unexpected end of definition "${this.#src}" What it means
The parser called #next() when the token stream was exhausted — the definition string ended where another token was required. Callers include t() (primary parsing), hi (right bound), limit (after == or %), and name (after #). This is the 'premature end of input' error for the string-definition mini-grammar.
Source
Thrown at packages/omptype/src/ir.ts:352
class StrParser {
#toks: Tok[];
#pos = 0;
#src: string;
#resolve: AliasResolver | undefined;
constructor(src: string, resolve?: AliasResolver) {
this.#src = src;
this.#resolve = resolve;
this.#toks = tokenize(src);
}
#peek(offset = 0): Tok | undefined {
return this.#toks[this.#pos + offset];
}
#next(): Tok {
const t = this.#toks[this.#pos++];
if (!t) throw new OmpTypeError(`unexpected end of definition "${this.#src}"`);
return t;
}
#eatOp(v: string): boolean {
const t = this.#peek();
if (t?.t === "op" && t.v === v) {
this.#pos++;
return true;
}
return false;
}
/** Full definition with optional trailing `= literal` default and/or `?` optional marker. */
parseTop(): ParsedTop {
const ir = this.parseUnion();
let def: unknown;
let hasDefault = false;
if (this.#eatOp("=")) {View on GitHub (pinned to 9690622007)
Solutions
- Append the missing token: a limit after a comparator ('number>=1'), an operand after '|' or '&', a ')' for '(', or an identifier after '#'.
- If the definition is interpolated, verify every interpolated value is defined and non-empty before building the string.
- Log/echo the full definition string (included in the message) and compare against expected syntax to spot truncation.
- Prefer composing from validated parts or use the object/IR form of the schema instead of string concatenation.
Example fix
// before
schema.parse("number>=");
// after
schema.parse("number>=1"); Defensive patterns
Strategy: validation
Validate before calling
function assertComplete(def) {
if (/[<>=|&%(#%]$/.test(def.trim())) throw new Error(`definition ends mid-construct: ${def}`);
} Try / catch
try {
const schema = parse(def);
} catch (e) {
if (String(e.message).includes("unexpected end of definition")) {
// log def and its length; check the interpolation that built it
}
throw e;
} Prevention
- Never end a definition with a dangling operator; always pair comparators with limits and brackets with closers.
- Assert every interpolated variable is defined and non-empty before composing the string.
- Build complex definitions from small, individually-parsed fragments instead of one long concatenation.
When it happens
Trigger: Definitions that stop mid-construct: 'string<' (generic without args), 'number>=' (bound without a limit), '5 %' (divisor missing), 'array#' (brand name missing), '(' (unclosed group reaching EOF), 'string|' (dangling union bar).
Common situations: Truncated strings from template concatenation (`number >= ${}` with undefined min printing as nothing is caught earlier, but a trailing operator is common); hand-edited schemas where a value was deleted; string slicing that chopped the tail off a definition.
Related errors
- Malformed number literal '${raw}'
- unexpected character '${c}' in "${src}"
- unsupported default literal in "${this.#src}"
- trailing tokens in definition "${this.#src}"
- expected bound after comparator in "${this.#src}"
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/3ee8dc850b40b871.
Report an issue: GitHub.