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

  1. Wrap the value in an omptype type: string, number(string), literal(42), etc.
  2. If integrating another validator, convert it to an omptype schema first
  3. Check that you did not shadow the imported string/number helpers with local variables
  4. 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

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


AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31). Data as JSON: /api/errors/d0b245b2f92d6fb9. Report an issue: GitHub.