{"id":"dea2532f44afd7dc","repo":"colinhacks/zod","slug":"unrecognized-key-key","errorCode":null,"errorMessage":"Unrecognized key: \"${key}\"","messagePattern":"Unrecognized key: \"(.+?)\"","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/zod/src/v4/core/util.ts","lineNumber":615,"sourceCode":"  int64: [/* @__PURE__*/ BigInt(\"-9223372036854775808\"), /* @__PURE__*/ BigInt(\"9223372036854775807\")],\n  uint64: [/* @__PURE__*/ BigInt(0), /* @__PURE__*/ BigInt(\"18446744073709551615\")],\n};\n\nexport function pick(schema: schemas.$ZodObject, mask: Record<string, unknown>): any {\n  const currDef = schema._zod.def;\n\n  const checks = currDef.checks;\n  const hasChecks = checks && checks.length > 0;\n  if (hasChecks) {\n    throw new Error(\".pick() cannot be used on object schemas containing refinements\");\n  }\n\n  const def = mergeDefs(schema._zod.def, {\n    get shape() {\n      const newShape: Writeable<schemas.$ZodShape> = {};\n      for (const key in mask) {\n        if (!(key in currDef.shape)) {\n          throw new Error(`Unrecognized key: \"${key}\"`);\n        }\n        if (!mask[key]) continue;\n        newShape[key] = currDef.shape[key]!;\n      }\n\n      assignProp(this, \"shape\", newShape); // self-caching\n      return newShape;\n    },\n    checks: [],\n  });\n\n  return clone(schema, def) as any;\n}\n\nexport function omit(schema: schemas.$ZodObject, mask: object): any {\n  const currDef = schema._zod.def;\n\n  const checks = currDef.checks;","sourceCodeStart":597,"sourceCodeEnd":633,"githubUrl":"https://github.com/colinhacks/zod/blob/912f0f51b0ced654d0069741e7160834dca742ee/packages/zod/src/v4/core/util.ts#L597-L633","documentation":"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).","triggerScenarios":"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.","commonSituations":"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.","solutions":["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.","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>`.","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."],"exampleFix":"// before\nconst Picked = User.pick({ usernme: true }); // typo\n\n// after\nconst Picked = User.pick({ username: true });","handlingStrategy":"validation","validationCode":"const mask = { username: true };\nconst shape = schema._zod.def.shape;\nfor (const k of Object.keys(mask)) {\n  if (!(k in shape)) throw new Error(`mask key '${k}' not in schema`);\n}\nconst Picked = schema.pick(mask);","typeGuard":"function isShapeKey<T extends z.core.$ZodObject>(s: T, k: string): k is keyof T['_zod']['def']['shape'] {\n  return k in s._zod.def.shape;\n}","tryCatchPattern":null,"preventionTips":["Type every mask as `Partial<Record<keyof z.infer<typeof schema>, boolean>>` so unknown keys fail to compile.","Centralize masks alongside the schema definition so renames update them in one place."],"tags":["zod","object-schema","pick","typo"],"analyzedSha":"912f0f51b0ced654d0069741e7160834dca742ee","analyzedAt":"2026-08-03T17:41:55.908Z","schemaVersion":2}