colinhacks/zod · error · Error

Unrecognized key: "${key}"

Error message

Unrecognized key: "${key}"

What it means

Thrown by Zod v4's `.pick()` when the mask passed to the method contains a key that does not exist on the source object schema's shape. The library treats unknown keys as a programming error because picking a nonexistent field would silently produce an empty shape and hide a typo. It fires inside the lazily-evaluated shape getter, so it triggers on the first access of the resulting schema's shape (e.g. during parsing).

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 912f0f51b0)

Solutions

  1. Compare the keys in your pick mask against `keyof typeof schema` (or the inferred object type) and remove or correct any that don't match.
  2. If using a shared mask constant, derive it from the schema's keys: `type K = keyof z.infer<typeof schema>` and constrain the mask to `Record<K, boolean>`.
  3. Regenerate the schema after renames via TypeScript's compiler errors — annotate the mask with the exact key set so unknown keys fail at compile time.

Example fix

// before
const Picked = User.pick({ usernme: true }); // typo

// after
const Picked = User.pick({ username: true });
Defensive patterns

Strategy: validation

Validate before calling

const mask = { username: true };
const shape = schema._zod.def.shape;
for (const k of Object.keys(mask)) {
  if (!(k in shape)) throw new Error(`mask key '${k}' not in schema`);
}
const Picked = schema.pick(mask);

Type guard

function isShapeKey<T extends z.core.$ZodObject>(s: T, k: string): k is keyof T['_zod']['def']['shape'] {
  return k in s._zod.def.shape;
}

Prevention

When it happens

Trigger: Calling `schema.pick({ foo: true })` where `foo` is not a key of `schema`'s defined object shape. The check at util.ts:614 (`if (!(key in currDef.shape))`) fires per key in the mask.

Common situations: Renaming a field in the base schema and forgetting to update the pick mask; copying a mask from a similar but different schema; typos in mask keys; picking after an `.omit()` that already removed the field.

Related errors


AI-assisted analysis of colinhacks/zod@912f0f51b0 (2026-08-03). Data as JSON: /data/errors/dea2532f44afd7dc.json. Report an issue: GitHub.