can1357/oh-my-pi · error · OmpTypeError

mapped property ${String(property.key)} has invalid kind

Error message

mapped property ${String(property.key)} has invalid kind

What it means

omptype throws this while converting an object property to its internal IR representation. Every TypeProperty must have kind 'required' or 'optional'; anything else means the property object was malformed or constructed outside the library's public builders. The library refuses to compile an object schema with an unknown property kind rather than silently guessing optionality.

Source

Thrown at packages/omptype/src/type.ts:1757

}

function mergeObjectDefinition(ir: IR, definition: unknown, resolve?: AliasResolver): ObjectIR {
	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);

View on GitHub (pinned to 9690622007)

Solutions

  1. Build properties with the library's required()/optional() helpers instead of literal objects
  2. Log String(property.key) from the message to find the offending key and inspect its kind value
  3. Check for version drift: internal kinds are not public API; regenerate any code that constructs TypeProperty directly
  4. Assert kind at your boundary before passing a property into type()

Example fix

// before
type({ name: { key: 'name', kind: 'maybe', value: string } })
// after
type({ name: optional(string) })
Defensive patterns

Strategy: validation

Validate before calling

function isValidProperty(p) {
  return p && (p.kind === 'required' || p.kind === 'optional') && p.value && String(p.key).length > 0;
}
// call before type({...}): Object.values(props).every(isValidProperty)

Type guard

function isTypeProperty(p): p is TypeProperty {
  return typeof p === 'object' && p !== null && (p.kind === 'required' || p.kind === 'optional') && IR_BRAND in p.value;
}

Try / catch

try {
  const T = type(props);
} catch (err) {
  if (err instanceof OmpTypeError && err.message.includes('invalid kind')) {
    throw new Error(`bad property definition: ${err.message}`);
  }
  throw err;
}

Prevention

When it happens

Trigger: Calling a builder (e.g. type({...})) with a property whose kind field was hand-crafted or corrupted, or passing a mapped/computed property object that skipped the required/optional normalization step.

Common situations: Hand-writing TypeProperty objects instead of using helpers like required()/optional(); upgrading omptype and relying on a removed internal kind value; a custom mapper producing properties without setting kind.

Related errors


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