colinhacks/zod · error · Error

Unrecognized key

Error message

Unrecognized key: "${key}"

What it means

Thrown by the pick() helper when iterating the supplied mask: every key in the mask must already exist in the object schema's shape. The mask is treated as a closed allow-list, so a typo'd or stale key is rejected rather than silently ignored. This surfaces at `.pick()` call time inside the lazy shape getter.

Solutions

  1. Check the error message for the exact offending key and correct the mask to match the schema's defined fields.
  2. If building the mask dynamically, filter candidate keys against `Object.keys(schema._zod.def.shape)` (or the inferred keys) before calling `.pick()`.
  3. Update renamed fields across all `.pick()` call sites during a refactor.

Example fix

// before
const S = z.object({ id: z.string(), name: z.string() });
S.pick({ nmae: true }); // throws: Unrecognized key "nmae"

// after
S.pick({ name: true });
Defensive patterns

Strategy: validation

Validate before calling

function buildPickMask<T extends z.ZodObject>(schema: T, want: string[]): Record<string, true> {
  const known = new Set(Object.keys((schema as any)._zod.def.shape));
  const mask: Record<string, true> = {};
  for (const k of want) {
    if (!known.has(k)) throw new TypeError(`Unrecognized key for pick(): ${String(k)}`);
    mask[k] = true;
  }
  return mask;
}
// schema.pick(buildPickMask(schema, ['a', 'b']));

Type guard

function isKnownKey(schema: z.ZodObject, key: PropertyKey): boolean {
  return Object.prototype.hasOwnProperty.call((schema as any)._zod.def.shape, key);
}

Prevention

When it happens

Trigger: Calling `schema.pick({ nmae: true })` where `nmae` is not a defined field; passing a mask built from an older version of the schema after a rename; generating the mask from a union of field names that includes keys not present on this particular object.

Common situations: Typos in the mask literal; copy-pasting a mask from a sibling schema; refactoring a field name without updating every `.pick()` site; programmatic mask construction from user input or config.

Related errors


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

Appendix: source

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

  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: [],
  });

  return clone(schema, def) as any;
}

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

  const checks = currDef.checks;

View on GitHub (pinned to 2d90846af9)