can1357/oh-my-pi · error · OmpTypeError

date bound must be valid

Error message

date bound must be valid

What it means

dateRefinement() validates the timestamp bound before attaching a date refinement. A non-finite timestamp (NaN, Infinity) cannot form a valid Date bound, so omptype throws instead of producing a schema that could never match or would match everything.

Source

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

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

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>();

View on GitHub (pinned to 9690622007)

Solutions

  1. Validate the timestamp with Number.isFinite(new Date(value).getTime()) before calling the bound API
  2. Use a strict date parser for user/config input and fail early on invalid strings
  3. Check that a variable holding the bound is not undefined coerced through Date.parse

Example fix

// before
const ts = Date.parse(config.until); date.max(ts)
// after
const ts = Date.parse(config.until);
if (!Number.isFinite(ts)) throw new Error(`invalid date: ${config.until}`);
date.max(ts)
Defensive patterns

Strategy: validation

Validate before calling

function assertValidDateBound(value) {
  const ts = value instanceof Date ? value.getTime() : new Date(value).getTime();
  if (!Number.isFinite(ts)) throw new Error(`invalid date bound: ${value}`);
  return ts;
}

Type guard

function isFiniteDate(d): d is Date {
  return d instanceof Date && Number.isFinite(d.getTime());
}

Try / catch

try {
  return date().min(bound);
} catch (err) {
  if (err instanceof OmpTypeError && err.message === 'date bound must be valid') {
    logger.error('date bound parsed to NaN/Infinity', { bound });
    return fallbackSchema;
  }
  throw err;
}

Prevention

When it happens

Trigger: schema.minDate(Date.parse('not a date')) (NaN), schema.after(Number.POSITIVE_INFINITY), or computing a bound with a broken date parser.

Common situations: Parsing user-supplied date strings with Date.parse and not checking for NaN; arithmetic on dates producing NaN; timezone parse failures in config files.

Related errors


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