can1357/oh-my-pi · error · OmpTypeError

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

Error message

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

What it means

`.url()` marks a string schema as requiring a valid URL; calling it on any other schema kind throws this OmpTypeError. The message interpolates the actual IR kind. Thrown from `url()` at packages/omptype/src/zod.ts:185.

Source

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

			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> {
			return decorate(schema.or(type.raw("null")) as Decoratable<Out | null>, optional);
		},
		default(
			value: Exclude<Out, undefined> | (() => Exclude<Out, undefined>),
		): ZodLikeSchema<Exclude<Out, undefined>> {
			type DefaultOut = Exclude<Out, undefined>;
			const widened = schema.or(type.raw("undefined")) as Decoratable<Out | undefined>;
			const piped = widened.pipe(output => {
				if (output !== undefined) return output as DefaultOut;
				return typeof value === "function" ? (value as () => DefaultOut)() : value;
			}) as Decoratable<DefaultOut>;

View on GitHub (pinned to 9690622007)

Solutions

  1. Call .url() only on t.string() schemas
  2. If the value is not a string, transform or retype the field to t.string().url()
  3. Remove the .url() call if the field does not hold a URL

Example fix

// before
t.object({ port: t.number().url() })
// after
t.object({ endpoint: t.string().url(), port: t.number() })
Defensive patterns

Strategy: type-guard

Validate before calling

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

Type guard

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

Try / catch

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

Prevention

When it happens

Trigger: `t.number().url()`, `.url()` on boolean/object/union schemas; chaining .url() after transforms that changed the schema kind.

Common situations: Config/endpoint fields retyped from string to something else while keeping .url(); generic builders applying .url() to all 'location'-ish fields; copy-paste between URL and non-URL field definitions.

Related errors


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