{"id":"4197025d4bd6c1a4","repo":"colinhacks/zod","slug":"invalid-element-at-key-k-expected-a-zod-sche","errorCode":null,"errorMessage":"Invalid element at key \"${k}\": expected a Zod schema","messagePattern":"Invalid element at key \"(.+?)\": expected a Zod schema","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/zod/src/v4/core/schemas.ts","lineNumber":1842,"sourceCode":"  propValues: util.PropValues;\n  output: $InferObjectOutput<Shape, Config[\"out\"]>;\n  input: $InferObjectInput<Shape, Config[\"in\"]>;\n  optin?: \"optional\" | undefined;\n  optout?: \"optional\" | undefined;\n}\nexport type $ZodLooseShape = Record<string, any>;\n\nexport interface $ZodObject<\n  /** @ts-ignore Cast variance */\n  out Shape extends Readonly<$ZodShape> = Readonly<$ZodShape>,\n  out Params extends $ZodObjectConfig = $ZodObjectConfig,\n> extends $ZodType<any, any, $ZodObjectInternals<Shape, Params>> {}\n\nfunction normalizeDef(def: $ZodObjectDef) {\n  const keys = Object.keys(def.shape);\n  for (const k of keys) {\n    if (!def.shape?.[k]?._zod?.traits?.has(\"$ZodType\")) {\n      throw new Error(`Invalid element at key \"${k}\": expected a Zod schema`);\n    }\n  }\n  const okeys = util.optionalKeys(def.shape);\n\n  return {\n    ...def,\n    keys,\n    keySet: new Set(keys),\n    numKeys: keys.length,\n    optionalKeys: new Set(okeys),\n  };\n}\n\nfunction handleCatchall(\n  proms: Promise<any>[],\n  input: any,\n  payload: ParsePayload,\n  ctx: ParseContext,","sourceCodeStart":1824,"sourceCodeEnd":1860,"githubUrl":"https://github.com/colinhacks/zod/blob/912f0f51b0ced654d0069741e7160834dca742ee/packages/zod/src/v4/core/schemas.ts#L1824-L1860","documentation":"`normalizeDef` (schemas.ts:1838) walks every key of an object's shape and asserts each value has the `$ZodType` trait (`def.shape[k]._zod.traits.has(\"$ZodType\")`). If any value is a plain object, primitive, class, or non-Zod schema, it throws `Invalid element at key \"${k}\"` at construction time. This catches mistakes where a field is given a raw value instead of a Zod schema.","triggerScenarios":"Constructing `z.object({ foo: \"string\" })`, `z.object({ count: 0 })`, `z.object({ nested: { x: z.string() } })` (raw object instead of `z.object()`), or passing a Yup/Joi schema. Any value lacking `_zod.traits` triggers it.","commonSituations":"Forgetting the `z.` prefix (writing `string` instead of `z.string()`); nesting raw config objects; copy-pasting TypeScript types into runtime schemas; importing a schema that is actually `undefined` due to a bad import path.","solutions":["Wrap every field value in a Zod schema: `z.object({ foo: z.string() })`.","For nested data use `z.object()` recursively rather than a plain object.","Check the offending key named in the error message and ensure its value is a Zod schema instance."],"exampleFix":"// before\nconst S = z.object({ name: \"string\", count: 0 }); // throws at 'name'\n// after\nconst S = z.object({ name: z.string(), count: z.number() });","handlingStrategy":"validation","validationCode":"import { z } from \"zod\";\n\nfunction isZodSchema(v: unknown): v is z.ZodType {\n  return !!v && typeof v === \"object\" && !!(v as any)?._zod?.traits?.has(\"$ZodType\");\n}\n\nfunction assertObjectShape(shape: Record<string, unknown>) {\n  for (const [k, v] of Object.entries(shape)) {\n    if (!isZodSchema(v)) {\n      throw new Error(`Invalid element at key \"${k}\": expected a Zod schema`);\n    }\n  }\n}","typeGuard":"import { z } from \"zod\";\n\nfunction isZodSchema(v: unknown): v is z.ZodType {\n  return !!v && typeof v === \"object\" && !!(v as any)?._zod?.traits?.has(\"$ZodType\");\n}\n\n// Usage: Object.values(shape).every(isZodSchema)","tryCatchPattern":null,"preventionTips":["Always wrap field values with a `z.*()` constructor; never pass raw primitives or plain objects.","For nested data use `z.object()` recursively, not a literal `{}`.","If a field looks like a schema but throws, check its import path (a bad import resolves to `undefined`)."],"tags":["object","shape","construction-time","schema-mistake"],"analyzedSha":"912f0f51b0ced654d0069741e7160834dca742ee","analyzedAt":"2026-08-03T17:41:55.908Z","schemaVersion":2}