colinhacks/zod · error · Error
.pick() cannot be used on object schemas containing…
Error message
.pick() cannot be used on object schemas containing refinements
What it means
Thrown by the internal pick() helper (the engine behind `.pick()`). Zod v4 attaches refinements (`.refine()`, `.check()`) to the object schema itself via `def.checks`, and `.pick()` produces a new schema with a fresh empty checks array. Silently dropping refinements during a sub-selection would be a correctness hazard, so the operation is hard-blocked whenever `def.checks.length > 0`.
Solutions
- Move the refinement onto the relevant leaf field or re-apply it after `.pick()` so the new schema owns it explicitly.
- Drop the refinement from the source object before picking (or use a refinement-free variant of the schema for the DTO).
- Build the picked schema from scratch and add the refinement scoped to the reduced field set.
Example fix
// before
const User = z.object({ a: z.string(), b: z.string() }).refine(v => v.a === v.b);
const Picked = User.pick({ a: true }); // throws
// after
const Picked = z.object({ a: z.string() });
// re-apply only the refinement logic that still applies Defensive patterns
Strategy: validation
Validate before calling
function canPick(schema: z.ZodObject): boolean {
const checks = (schema as any)._zod?.def?.checks;
return !checks || checks.length === 0;
}
// if (!canPick(MyObject)) { /* refactor: 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
- Keep refinement-free base schemas for slicing (pick/omit/partial) and layer refinements on per-variant.
- Prefer field-level `.refine()` over object-level when you also need to transform the schema.
- Document which schemas are 'safe to slice' vs 'carry invariants'.
When it happens
Trigger: Calling `myObject.pick({ a: true })` on an object that was built with `.refine(...)`, `.refine(...).refine(...)`, `.check(...)`, or any check that lands on the object node. The throw happens eagerly at the `.pick()` call, not at parse time.
Common situations: Building a base schema with a cross-field refinement (e.g. password/confirm equality) and then sub-selecting fields for a form subset; sharing a domain schema that carries invariants and slicing it for an API DTO; refactoring a flat schema by adding `.refine()` upstream of an existing `.pick()`.
Related errors
- Cannot overwrite keys on object schemas containing…
- .merge() cannot be used on object schemas containing…
- .omit() cannot be used on object schemas containing…
- .partial() cannot be used on object schemas containing…
- Invalid input to extend: expected a plain object
AI-assisted analysis of colinhacks/zod@2d90846af9 (2026-08-11).
Data as JSON: /api/errors/a614f04c6326c4b0.
Report an issue: GitHub.
Appendix: source
Thrown at packages/zod/src/v4/core/util.ts:607
safeint: [Number.MIN_SAFE_INTEGER, Number.MAX_SAFE_INTEGER],
int32: [-2147483648, 2147483647],
uint32: [0, 4294967295],
float32: [-3.4028234663852886e38, 3.4028234663852886e38],
float64: [-Number.MAX_VALUE, Number.MAX_VALUE],
};
export const BIGINT_FORMAT_RANGES: Record<checks.$ZodBigIntFormats, [bigint, bigint]> = {
int64: [/* @__PURE__*/ BigInt("-9223372036854775808"), /* @__PURE__*/ BigInt("9223372036854775807")],
uint64: [/* @__PURE__*/ BigInt(0), /* @__PURE__*/ BigInt("18446744073709551615")],
};
export function pick(schema: schemas.$ZodObject, mask: Record<string, unknown>): any {
const currDef = schema._zod.def;
const checks = currDef.checks;
const hasChecks = checks && checks.length > 0;
if (hasChecks) {
throw new Error(".pick() cannot be used on object schemas containing refinements");
}
const def = mergeDefs(schema._zod.def, {
get shape() {
const newShape: Writeable<schemas.$ZodShape> = {};
for (const key in mask) {
if (!(key in currDef.shape)) {
throw new Error(`Unrecognized key: "${key}"`);
}
if (!mask[key]) continue;
newShape[key] = currDef.shape[key]!;
}
assignProp(this, "shape", newShape); // self-caching
return newShape;
},
checks: [],
});View on GitHub (pinned to 2d90846af9)