can1357/oh-my-pi · error · OmpTypeError

cannot apply regex to ${schema.ir.k}

Error message

cannot apply regex to ${schema.ir.k}

What it means

`.regex()` tests a string value against a RegExp and is only valid on string schemas; calling it on any other kind throws this OmpTypeError. The message interpolates the actual IR kind. Thrown from `regex()` at packages/omptype/src/zod.ts:174.

Source

Thrown at packages/omptype/src/zod.ts:174

			}
			throw new OmpTypeError(`cannot apply max to ${ir.k}`);
		},
		int(): ZodLikeSchema<Out> {
			if (schema.ir.k !== "number") throw new OmpTypeError(`cannot apply int to ${schema.ir.k}`);
			return next(restrictBase(schema, { ...schema.ir, int: true }));
		},
		positive(): ZodLikeSchema<Out> {
			if (schema.ir.k !== "number") throw new OmpTypeError(`cannot apply positive to ${schema.ir.k}`);
			const ir = schema.ir;
			if (ir.min !== undefined && ir.min > 0) return next(restrictBase(schema, ir));
			return next(restrictBase(schema, { ...ir, min: 0, xmin: true }));
		},
		nonnegative(): ZodLikeSchema<Out> {
			if (schema.ir.k !== "number") throw new OmpTypeError(`cannot apply nonnegative to ${schema.ir.k}`);
			return this.min(0);
		},
		regex(expression: RegExp, message?: string): ZodLikeSchema<Out> {
			if (schema.ir.k !== "string") throw new OmpTypeError(`cannot apply regex to ${schema.ir.k}`);
			const expectation = message ?? `matching ${expression}`;
			const narrowed = schema.narrow((value, ctx) => {
				expression.lastIndex = 0;
				const matches = expression.test(value as string);
				expression.lastIndex = 0;
				return matches || ctx.mustBe(expectation);
			});
			return next(narrowed);
		},
		url(): ZodLikeSchema<Out> {
			if (schema.ir.k !== "string") throw new OmpTypeError(`cannot apply url to ${schema.ir.k}`);
			return next(restrictBase(schema, { ...schema.ir, url: true }));
		},
		optional(): ZodLikeSchema<Out | undefined> & OptionalSchemaMarker {
			const widened = schema.or(type.raw("undefined")) as Decoratable<Out | undefined>;
			return decorate(widened, true) as ZodLikeSchema<Out | undefined> & OptionalSchemaMarker;
		},
		nullable(): ZodLikeSchema<Out | null> {

View on GitHub (pinned to 9690622007)

Solutions

  1. Call .regex() only on t.string() schemas
  2. For numbers use numeric bounds/constraints instead of regex
  3. If the raw value is a string containing a number, keep the field as t.string().regex(...) or transform to number first

Example fix

// before
t.number().regex(/^\d+$/)
// after
t.string().regex(/^\d+$/)
// or numeric constraint:
t.number().int().nonnegative()
Defensive patterns

Strategy: type-guard

Validate before calling

function canApplyRegex(schema: ZodLikeSchema<unknown>): boolean {
  return schema.ir.k === "string";
}
if (!canApplyRegex(schema)) throw new Error("regex() requires a string schema");

Type guard

function isStringSchema(ir: { k: string }): ir is { k: "string" } {
  return ir.k === "string";
}

Try / catch

try {
  schema = base.regex(pattern);
} catch (err) {
  if (err instanceof OmpTypeError && err.message.startsWith("cannot apply regex")) {
    throw new Error("field must be t.string() to use .regex()");
  } else throw err;
}

Prevention

When it happens

Trigger: `t.number().regex(/.../)`, `.regex()` on boolean/object/array schemas; or forgetting that the value must already be a string at validation time.

Common situations: Validating patterns on values that come from inputs/APIs as strings but were typed as number in the schema; generic field validators that apply a pattern to every field; copy-paste between string and non-string field definitions.

Related errors


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