can1357/oh-my-pi · error · OmpTypeError
object mode requires an object schema
Error message
object mode requires an object schema
What it means
The zod-compat methods `.strict()`, `.passthrough()`, and `.strip()` only make sense for object schemas; they call `withObjectExtras`, which throws `object mode requires an object schema` when the underlying schema's IR kind is not `object`.
Source
Thrown at packages/omptype/src/zod.ts:109
function isStringKeyIR(ir: IR): boolean {
switch (ir.k) {
case "string":
return true;
case "lit":
return typeof ir.v === "string";
case "union":
return ir.members.length > 0 && ir.members.every(isStringKeyIR);
case "sub":
return isStringKeyIR(ir.schema.ir);
default:
return false;
}
}
function decorate<Out>(schema: Decoratable<Out>, optional = false): ZodLikeSchema<Out> {
const next = (inner: Decoratable<Out>, nextOptional = optional): ZodLikeSchema<Out> => decorate(inner, nextOptional);
const withObjectExtras = (extras: "keep" | "reject" | "delete"): ZodLikeSchema<Out> => {
if (schema.ir.k !== "object") throw new OmpTypeError("object mode requires an object schema");
return next(restrictBase(schema, { ...schema.ir, extras }));
};
Object.defineProperty(schema, "isOptional", { value: optional, enumerable: false });
return Object.assign(schema, {
parse(value: unknown): Out {
const result = schema(value);
if (result instanceof type.errors) throw new Error(result.summary);
return result;
},
safeParse(value: unknown): ZodLikeSafeParseResult<Out> {
const result = schema(value);
if (!(result instanceof type.errors)) return { success: true, data: result };
return {
success: false,
error: {
message: result.summary,
issues: result.map(issue => ({ path: [...issue.path], message: issue.problem })),View on GitHub (pinned to 9690622007)
Solutions
- Only call `.strict()`/`.passthrough()`/`.strip()` on `z.object({...})` schemas.
- If the schema kind varies, gate the call: `if (schema.ir.k === 'object') schema.strict()` or use a typed TObject parameter.
- Remove the mode call if the intent was only decoration — these methods are object-specific.
Example fix
// before
function define(s: any) { return s.strict(); }
define(z.string()); // throws
// after
function define(s: ZodLikeSchema<{ id: string }>) { return s.strict(); }
define(z.object({ id: z.string() })); Defensive patterns
Strategy: type-guard
Validate before calling
// narrow to object schemas before applying modes
if (schema.ir.k !== "object") throw new Error("strict()/passthrough() require an object schema");
schema.strict(); Type guard
function isObjectSchema(s: ZodLikeSchema<unknown>): boolean {
return (s as unknown as { ir: { k: string } }).ir.k === "object";
} Try / catch
try {
const strict = maybeSchema.strict();
} catch (err) {
if (err instanceof Error && err.message === 'object mode requires an object schema') {
return maybeSchema; // modes only apply to objects — pass through unchanged
}
throw err;
} Prevention
- Restrict strict/passthrough/strip call sites to values typed as object schemas.
- In generic helpers, check `schema.ir.k === 'object'` before applying a mode.
- Avoid unconditionally chaining .strict() on schemas of dynamic kinds.
When it happens
Trigger: `z.string().strict()`, `z.array(el).passthrough()`, `z.object({...}).strict()` is fine but `z.union([...]).strict()` throws; also calling strict/passthrough/strip on a schema that was narrowed from object to something else.
Common situations: Generic wrapper functions that unconditionally chain `.strict()` on schemas of varying kinds; copying a builder chain to a non-object type during refactors.
Related errors
- Type.${operation} requires a schema created by Type.Object
- cannot apply min to ${ir.k}
- ${name} must be finite
- invalid regular expression pattern ${JSON.stringify(opts.pat
- multipleOf must be greater than zero
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/063b2c54ad0de70e.
Report an issue: GitHub.