{"record":{"id":"1863448cb05215ed","repo":"can1357/oh-my-pi","slug":"cannot-apply-positive-to-schema-ir-k","errorCode":null,"errorMessage":"cannot apply positive to ${schema.ir.k}","messagePattern":"cannot apply positive to (.+?)","errorType":"exception","errorClass":"OmpTypeError","httpStatus":null,"severity":"error","filePath":"packages/omptype/src/zod.ts","lineNumber":164,"sourceCode":"\t\t\tconst ir = schema.ir;\n\t\t\tif (ir.k === \"string\" || ir.k === \"array\") {\n\t\t\t\tlengthBound(\"max\", schema, bound);\n\t\t\t\tconst max = ir.max === undefined ? bound : Math.min(ir.max, bound);\n\t\t\t\treturn next(restrictBase(schema, { ...ir, max }));\n\t\t\t}\n\t\t\tif (ir.k === \"number\") {\n\t\t\t\tif (Number.isNaN(bound)) throw new OmpTypeError(\"number max must not be NaN\");\n\t\t\t\tif (ir.max !== undefined && ir.max <= bound) return next(restrictBase(schema, ir));\n\t\t\t\treturn next(restrictBase(schema, { ...ir, max: bound, xmax: false }));\n\t\t\t}\n\t\t\tthrow new OmpTypeError(`cannot apply max to ${ir.k}`);\n\t\t},\n\t\tint(): ZodLikeSchema<Out> {\n\t\t\tif (schema.ir.k !== \"number\") throw new OmpTypeError(`cannot apply int to ${schema.ir.k}`);\n\t\t\treturn next(restrictBase(schema, { ...schema.ir, int: true }));\n\t\t},\n\t\tpositive(): ZodLikeSchema<Out> {\n\t\t\tif (schema.ir.k !== \"number\") throw new OmpTypeError(`cannot apply positive to ${schema.ir.k}`);\n\t\t\tconst ir = schema.ir;\n\t\t\tif (ir.min !== undefined && ir.min > 0) return next(restrictBase(schema, ir));\n\t\t\treturn next(restrictBase(schema, { ...ir, min: 0, xmin: true }));\n\t\t},\n\t\tnonnegative(): ZodLikeSchema<Out> {\n\t\t\tif (schema.ir.k !== \"number\") throw new OmpTypeError(`cannot apply nonnegative to ${schema.ir.k}`);\n\t\t\treturn this.min(0);\n\t\t},\n\t\tregex(expression: RegExp, message?: string): ZodLikeSchema<Out> {\n\t\t\tif (schema.ir.k !== \"string\") throw new OmpTypeError(`cannot apply regex to ${schema.ir.k}`);\n\t\t\tconst expectation = message ?? `matching ${expression}`;\n\t\t\tconst narrowed = schema.narrow((value, ctx) => {\n\t\t\t\texpression.lastIndex = 0;\n\t\t\t\tconst matches = expression.test(value as string);\n\t\t\t\texpression.lastIndex = 0;\n\t\t\t\treturn matches || ctx.mustBe(expectation);\n\t\t\t});\n\t\t\treturn next(narrowed);","sourceCodeStart":146,"sourceCodeEnd":182,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/omptype/src/zod.ts#L146-L182","documentation":"`.positive()` asserts a strict lower bound (value > 0) and therefore only exists for number schemas; calling it on any other kind throws this OmpTypeError. The message interpolates the actual IR kind. Thrown from `positive()` at packages/omptype/src/zod.ts:164.","triggerScenarios":"`t.string().positive()`, `t.boolean().positive()`, `.positive()` on object/array/union schemas.","commonSituations":"Schema chains where a numeric field was retyped to string (e.g. amounts from form inputs as strings) while the sign constraint remained; generic builders that apply positivity uniformly; copy-paste between numeric and non-numeric field definitions.","solutions":["Call .positive() only on t.number() schemas","If the value is a numeric string, switch the field to t.number() (or transform before validating)","For inclusive >= 0 semantics use .nonnegative() on a number schema instead"],"exampleFix":"// before\nt.string().positive()\n// after\nt.number().positive()","handlingStrategy":"type-guard","validationCode":"function canApplyPositive(schema: ZodLikeSchema<unknown>): boolean {\n  return schema.ir.k === \"number\";\n}\nif (!canApplyPositive(schema)) throw new Error(\"positive() requires a number schema\");","typeGuard":"function isNumberSchema(ir: { k: string }): ir is { k: \"number\" } {\n  return ir.k === \"number\";\n}","tryCatchPattern":"try {\n  schema = base.positive();\n} catch (err) {\n  if (err instanceof OmpTypeError && err.message.startsWith(\"cannot apply positive\")) {\n    throw new Error(\"field must be t.number() to use .positive()\");\n  } else throw err;\n}","preventionTips":["Keep sign constraints chained directly after t.number()","Choose .positive() vs .nonnegative() deliberately (>0 vs >=0) when porting Zod code","Retype numeric-string form fields to t.number() with a transform before sign constraints"],"tags":["schema-builder","type-mismatch","number"],"backgroundTag":"schema-method-kind-mismatch","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}