colinhacks/zod · error · Error

.omit() cannot be used on object schemas containing…

Error message

.omit() cannot be used on object schemas containing refinements

What it means

Thrown by the omit() helper. Identical contract to `.pick()`: `.omit()` rebuilds the schema with an empty checks array, so dropping object-level refinements silently is forbidden. The guard fires whenever `def.checks.length > 0` on the source object.

Solutions

  1. Re-apply the refinement to the omitted result so it is not silently lost.
  2. Factor out a refinement-free base schema and call `.omit()` on that, layering refinements on each variant.
  3. Build the public schema from scratch with only the needed fields.

Example fix

// before
const User = z.object({ email: z.string(), pwd: z.string() })
  .refine(v => v.email.length > 0);
const Public = User.omit({ pwd: true }); // throws

// after
const Public = z.object({ email: z.string() })
  .refine(v => v.email.length > 0);
Defensive patterns

Strategy: validation

Validate before calling

function canOmit(schema: z.ZodObject): boolean {
  const checks = (schema as any)._zod?.def?.checks;
  return !checks || checks.length === 0;
}
// if (!canOmit(MyObject)) { /* drop refinement or rebuild */ }

Type guard

function hasObjectRefinements(schema: z.ZodObject): boolean {
  const checks = (schema as any)._zod?.def?.checks;
  return Array.isArray(checks) && checks.length > 0;
}

Prevention

When it happens

Trigger: Calling `myObject.omit({ secret: true })` where `myObject` has a `.refine()`, `.check()`, or any object-level refinement attached. Eager throw at the `.omit()` call site.

Common situations: Stripping sensitive fields (passwordHash, internal flags) from a schema that also enforces a cross-field invariant; reusing a domain entity schema for a public response shape; adding a refinement upstream and forgetting an existing `.omit()` depends on it.

Related errors


AI-assisted analysis of colinhacks/zod@2d90846af9 (2026-08-11). Data as JSON: /api/errors/e5bee1fc45abd1f0. Report an issue: GitHub.

Appendix: source

Thrown at packages/zod/src/v4/core/util.ts:636

        newShape[key] = currDef.shape[key]!;
      }

      assignProp(this, "shape", newShape); // self-caching
      return newShape;
    },
    checks: [],
  });

  return clone(schema, def) as any;
}

export function omit(schema: schemas.$ZodObject, mask: object): any {
  const currDef = schema._zod.def;

  const checks = currDef.checks;
  const hasChecks = checks && checks.length > 0;
  if (hasChecks) {
    throw new Error(".omit() cannot be used on object schemas containing refinements");
  }

  const def = mergeDefs(schema._zod.def, {
    get shape() {
      const newShape: Writeable<schemas.$ZodShape> = { ...schema._zod.def.shape };
      for (const key in mask) {
        if (!(key in currDef.shape)) {
          throw new Error(`Unrecognized key: "${key}"`);
        }
        if (!(mask as any)[key]) continue;

        delete newShape[key];
      }
      assignProp(this, "shape", newShape); // self-caching
      return newShape;
    },
    checks: [],
  });

View on GitHub (pinned to 2d90846af9)