can1357/oh-my-pi · error · OmpTypeError
ParseError: ${heading} ${error.problem}
Error message
ParseError: ${heading} ${error.problem} What it means
omptype wraps underlying parse failures in an OmpTypeError whose message is `ParseError: <heading> <problem>`. The heading is built from the type/property path segments where the default value was being normalized (e.g. `.myProp`), and `error.problem` describes why the default expression was rejected. `invalidDefault` is invoked by `normalizeDefaults` and `.default()` when a default fails validation against its own type.
Source
Thrown at packages/omptype/src/type.ts:623
target.resolver = source.resolver;
Reflect.set(target, "$", source.$);
return target;
}
function invalidDefault(label: string, errors: OmpErrors): never {
const error = errors[0];
let heading = label;
for (let index = 0; index < error.path.length; index++) {
const segment = error.path[index];
if (typeof segment === "number") {
if (label === "Default" && index === 0) heading = "Default value";
heading += ` at [${segment}]`;
} else if (label === "Default" && index === 0) {
heading += ` ${String(segment)}`;
} else {
heading += `.${String(segment)}`;
}
}
throw new OmpTypeError(`ParseError: ${heading} ${error.problem}`);
}
function rejectMutableStaticDefault(value: unknown): void {
if (value !== null && typeof value === "object" && !(value instanceof Date)) {
throw new OmpTypeError("ParseError: A mutable default value must be specified as a factory");
}
}
function normalizeDefaults(ir: IR, seen = new WeakSet<object>()): void {
if (seen.has(ir)) return;
seen.add(ir);
switch (ir.k) {
case "object":
for (const prop of ir.props) {
normalizeDefaults(prop.val, seen);
if (!prop.hasDefault || prop.defValidated) continue;
let candidate: unknown;
let factory = false;View on GitHub (pinned to 9690622007)
Solutions
- Read `error.problem` in the message — it states the exact constraint the default violates.
- Change the default to a value that satisfies the type (e.g. `type('number>5').default(10)`).
- Use a factory `.default(() => value)` if a computed or Date-valued default is intended.
- Re-check the path in the heading to find which nested property's default is wrong.
Example fix
// before
const T = type('number > 5').default(3); // ParseError
// after
const T = type('number > 5').default(10); Defensive patterns
Strategy: validation
Validate before calling
// validate the default against the type before calling .default
if (!T.allows(candidateDefault)) {
throw new Error(`default ${JSON.stringify(candidateDefault)} fails type`);
}
const T2 = T.default(candidateDefault); Type guard
function isValidDefault(T, value) {
return T.allows(value);
} Try / catch
try {
const T = type('number>5').default(3);
} catch (e) {
if (e instanceof OmpTypeError && e.message.startsWith('ParseError:')) {
console.error(e.message); // includes path heading + problem
} else throw e;
} Prevention
- Always check `.allows(defaultValue)` when defaults are computed dynamically.
- Keep type constraints and defaults defined together so refactors update both.
- Prefer factories for computed defaults to avoid stale literal values.
When it happens
Trigger: Calling `.default(value)` with a value that does not satisfy the type, or defining an object property default that fails its own constraint (e.g. `type('number > 5').default(3)`), or a nested prop default that violates the prop type.
Common situations: Refactoring a type's constraints after setting defaults so the stale default no longer validates; copy-pasting defaults between fields with different types; typos like `.default('1')` on a number type.
Related errors
- ParseError: A mutable default value must be specified as a f
- Invalid RAR5 archive: ${reason}
- Unsupported language '{value}'. Supported: {}
- Unable to infer language from file extension: {}. Specify `l
- Invalid pattern: {err}
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/28d56698ce12d0b1.
Report an issue: GitHub.