can1357/oh-my-pi · error · OmpTypeError
mapped property ${String(property.key)} must contain a schem
Error message
mapped property ${String(property.key)} must contain a schema value What it means
While converting a property to IR, omptype checks that property.value carries the internal IR brand (IR_BRAND), proving it is a real omptype schema. A plain value, a string like 'string', or a foreign validator was passed where a schema was expected. The library throws instead of treating the value as a literal.
Source
Thrown at packages/omptype/src/type.ts:1760
return mergeObjects(requireObject(ir, "merge"), requireObject(parseDef(definition, resolve), "merge"));
}
function propertyFromIR(prop: PropIR): TypeProperty {
return {
kind: prop.opt ? "optional" : "required",
key: prop.key,
value: makeType(prop.val, [], {}) as unknown as FluentType<unknown>,
...(prop.hasDefault ? { default: prop.def } : {}),
meta: {},
};
}
function propertyToIR(property: TypeProperty): PropIR {
if (property.kind !== "required" && property.kind !== "optional") {
throw new OmpTypeError(`mapped property ${String(property.key)} has invalid kind`);
}
if (!(IR_BRAND in property.value)) {
throw new OmpTypeError(`mapped property ${String(property.key)} must contain a schema value`);
}
const hasDefault = Object.hasOwn(property, "default");
return {
key: property.key,
opt: property.kind === "optional",
val: embed(property.value),
...(hasDefault
? { def: property.default, defFactory: typeof property.default === "function", hasDefault: true }
: {}),
};
}
function acceptsDateIR(ir: IR): boolean {
if (ir.k === "instance") return ir.ctor === Date;
if (ir.k === "refine") return acceptsDateIR(ir.base);
if (ir.k === "union") return ir.members.every(acceptsDateIR);
return false;
}View on GitHub (pinned to 9690622007)
Solutions
- Wrap the value in an omptype type: string, number(string), literal(42), etc.
- If integrating another validator, convert it to an omptype schema first
- Check that you did not shadow the imported string/number helpers with local variables
- Inspect the offending key from the error message and verify its value came from an omptype builder
Example fix
// before
type({ retries: 3 })
// after
type({ retries: literal(3) }) Defensive patterns
Strategy: validation
Validate before calling
function allValuesAreSchemas(props) {
return Object.values(props).every(v => v && typeof v === 'object' && '~ir' in v); // schema-brand check
} Type guard
function isOmpSchema(v): v is InternalType {
return typeof v === 'object' && v !== null && IR_BRAND in v;
} Try / catch
try {
const T = type(props);
} catch (err) {
if (err instanceof OmpTypeError && err.message.includes('must contain a schema value')) {
throw new Error('property value is not an omptype schema — wrap it with string()/number()/literal()');
}
throw err;
} Prevention
- Wrap raw values with literal()/enum() instead of passing them directly
- Never place foreign-library validators inside type()
- Keep an import-lint rule so string/number helpers are not shadowed
When it happens
Trigger: type({ age: 42 }) or type({ id: someZodSchema }) — passing raw values or third-party schema objects as property values instead of omptype types.
Common situations: Mixing validation libraries (zod/yup objects inside an omptype type()); forgetting to wrap literals (use literal(42)); typos like type({x: 'string'}).
Related errors
- mapped property ${String(property.key)} has invalid kind
- intersection has no satisfiable branches
- ParseError: Invalid intersection of default values ${String(
- cannot apply numeric bound to ${ir.k}
- invalid generic parameter "${parameter.name}"
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/d0b245b2f92d6fb9.
Report an issue: GitHub.