can1357/oh-my-pi · error · OmpTypeError

date bounds require a Date type

Error message

date bounds require a Date type

What it means

Date bounds (min/max/after/before) only apply to schemas whose IR is Date-shaped; acceptsDateIR() rejects anything else. Calling a date refinement on a string or number schema is almost always a mistake, so omptype throws at schema-construction time rather than failing every validation later.

Source

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

			: {}),
	};
}

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;
}

function dateRefinement(
	schema: InternalType,
	timestamp: number,
	relation: string,
	predicate: (value: number) => boolean,
): InternalType {
	if (!Number.isFinite(timestamp)) throw new OmpTypeError("date bound must be valid");
	if (!acceptsDateIR(schema.ir)) throw new OmpTypeError("date bounds require a Date type");
	const bound = new Date(timestamp);
	return makeType(
		{
			k: "refine",
			base: schema.ir,
			pred: value => value instanceof Date && predicate(value.valueOf()),
			expected: `a Date ${relation} ${bound.toISOString()}`,
			json: relation.includes("after") ? { minimum: bound.toISOString() } : { maximum: bound.toISOString() },
		},
		schema[kSteps],
		metaOf(schema),
	);
}

function selectNodes(root: IR, kind: string): readonly SelectedNode[] {
	const selected: SelectedNode[] = [];
	const seen = new Set<IR>();
	const visit = (node: IR): void => {

View on GitHub (pinned to 9690622007)

Solutions

  1. Apply the bound to a date() schema: date().min(...)
  2. For string dates use a string refinement (e.g. isoDateTime) or convert the schema to date()
  3. For numeric timestamps use a number refinement like number().min(timestamp)
  4. Check which field you called the method on; the wrong-variable bug is common

Example fix

// before
string().minDate(new Date('2024-01-01'))
// after
date().min(new Date('2024-01-01'))
Defensive patterns

Strategy: type-guard

Validate before calling

function assertDateSchema(schema) {
  if (!schema.ir || schema.ir.k !== 'refine' && !isDateShaped(schema.ir)) throw new Error('date bound needs a date() schema');
}

Type guard

function isDateSchema(t): t is InternalType {
  return typeof t === 'object' && t !== null && acceptsDateIR(t.ir);
}

Try / catch

try {
  return schema.min(bound);
} catch (err) {
  if (err instanceof OmpTypeError && err.message === 'date bounds require a Date type') {
    throw new Error('call date bounds on date(), not string()/number()');
  }
  throw err;
}

Prevention

When it happens

Trigger: string.minDate(...) or number.after(...) — any date refinement applied to a non-Date schema.

Common situations: Dates stored as ISO strings: developers reach for date bounds on string() instead of isoDate refinements; confusion after refactoring a Date field to a timestamp number.

Related errors


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