can1357/oh-my-pi · error · OmpTypeError
cannot apply nonnegative to ${schema.ir.k}
Error message
cannot apply nonnegative to ${schema.ir.k} What it means
`.nonnegative()` sets min 0 (inclusive) on number schemas; on any other schema kind it throws this OmpTypeError before delegating to `.min(0)`. The message interpolates the actual IR kind. Thrown from `nonnegative()` at packages/omptype/src/zod.ts:170.
Source
Thrown at packages/omptype/src/zod.ts:170
if (ir.k === "number") {
if (Number.isNaN(bound)) throw new OmpTypeError("number max must not be NaN");
if (ir.max !== undefined && ir.max <= bound) return next(restrictBase(schema, ir));
return next(restrictBase(schema, { ...ir, max: bound, xmax: false }));
}
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 {View on GitHub (pinned to 9690622007)
Solutions
- Call .nonnegative() only on t.number() schemas
- For arrays use .min(0) directly (array min is a length bound), not .nonnegative()
- Convert numeric-string fields to t.number() before applying sign constraints
Example fix
// before t.string().nonnegative() // after t.number().nonnegative()
Defensive patterns
Strategy: type-guard
Validate before calling
function canApplyNonnegative(schema: ZodLikeSchema<unknown>): boolean {
return schema.ir.k === "number";
}
if (!canApplyNonnegative(schema)) throw new Error("nonnegative() requires a number schema"); Type guard
function isNumberSchema(ir: { k: string }): ir is { k: "number" } {
return ir.k === "number";
} Try / catch
try {
schema = base.nonnegative();
} catch (err) {
if (err instanceof OmpTypeError && err.message.startsWith("cannot apply nonnegative")) {
throw new Error("field must be t.number() to use .nonnegative()");
} else throw err;
} Prevention
- For array length use .min(0) directly; reserve .nonnegative() for numbers
- Chain .nonnegative() immediately after t.number()
- Watch for retyped count/amount fields losing their number kind
When it happens
Trigger: `t.string().nonnegative()`, `.nonnegative()` on boolean/object/array/union schemas.
Common situations: Retyped fields (count/amount fields moving between string and number) that keep the sign constraint; generic validation helpers that apply .nonnegative() unconditionally; confusing array `.min(0)` length bounds with numeric nonnegativity.
Related errors
- cannot apply positive to ${schema.ir.k}
- number max must not be NaN
- cannot apply max to ${ir.k}
- cannot apply int to ${schema.ir.k}
- cannot apply regex to ${schema.ir.k}
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/cd127f6ceda6e9ab.
Report an issue: GitHub.