can1357/oh-my-pi · error · OmpTypeError
unexpected character '${c}' in "${src}"
Error message
unexpected character '${c}' in "${src}" What it means
The tokenizer hit a character that cannot start any token in an omptype string definition. Only digits, letters/_/$, quotes, '/', and known operators (SIMPLE_OPS, <, <=, >, >=, ==) are recognized; anything else (e.g. '@', '!', ';', ':', unicode punctuation) is rejected so that typos fail loudly instead of producing a mis-parsed schema.
Source
Thrown at packages/omptype/src/ir.ts:281
toks.push({ t: "op", v: `${c}=` });
i += 2;
} else {
toks.push({ t: "op", v: c });
i++;
}
continue;
}
if (c === "=" && src[i + 1] === "=") {
toks.push({ t: "op", v: "==" });
i += 2;
continue;
}
if (SIMPLE_OPS.includes(c)) {
toks.push({ t: "op", v: c });
i++;
continue;
}
throw new OmpTypeError(`unexpected character '${c}' in "${src}"`);
}
return toks;
}
// ── string-definition parser ─────────────────────────────────────────────────
const CMP: Record<string, true> = { "<": true, "<=": true, ">": true, ">=": true };
const KEYWORDS: Record<string, () => IR> = {
number: () => ({ k: "number" }),
"number.integer": () => ({ k: "number", int: true }),
boolean: () => ({ k: "boolean" }),
bigint: () => ({ k: "bigint" }),
symbol: () => ({ k: "symbol" }),
never: () => ({ k: "never" }),
null: () => ({ k: "null" }),
undefined: () => ({ k: "undefined" }),
unknown: () => ({ k: "unknown" }),View on GitHub (pinned to 9690622007)
Solutions
- Find the reported character in the echoed source string and remove or replace it with valid omptype syntax.
- Replace smart quotes/unicode punctuation with ASCII equivalents (' instead of ').
- Use '|' for unions and '&' for intersections instead of TS-style characters; consult the supported operator set (| & ( ) [ ] # % < <= > >= == = ? ,).
- If the string is built dynamically, sanitize/validate the interpolated fragment before composing the definition.
Example fix
// before
schema.parse("string@");
// after
schema.parse("string"); // or "string.email" etc. Defensive patterns
Strategy: validation
Validate before calling
const ALLOWED = /^[\w$.'"\/\s|&()\[\]#%<>=?,+\-:]/; // reject unknown chars up front
if (/[“”‘’]/.test(def)) throw new Error("smart quotes in definition"); Try / catch
try {
const schema = parse(def);
} catch (e) {
if (String(e.message).includes("unexpected character")) {
// strip/replace the offending char and retry once
}
throw e;
} Prevention
- Type definitions in an ASCII editor or lint for non-ASCII punctuation (smart quotes, en-dashes).
- Keep a list of the supported operators (| & ( ) [ ] # % < <= > >= == = ?) handy when hand-writing definitions.
- Sanitize user-supplied fragments before interpolating them into definition strings.
When it happens
Trigger: Any parse of a string definition containing an unsupported character: 'string@', 'number!', 'string; number', stray quotes/braces outside their grammar, or smart quotes ('“string”') pasted from docs.
Common situations: Copy-pasting type expressions from blogs/docs that contain smart quotes or non-ASCII dashes; typos like 'number!!'; using characters from a different type syntax (e.g. ':' or '=>' from TS); shell quoting mangling definition strings.
Related errors
- Malformed number literal '${raw}'
- unexpected end of definition "${this.#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/3e1063c0b8f8a8d2.
Report an issue: GitHub.