{"record":{"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":1853,"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":1835,"sourceCodeEnd":1871,"githubUrl":"https://github.com/colinhacks/zod/blob/2d90846af918af9602e088812d63a035d47cdbe4/packages/zod/src/v4/core/schemas.ts#L1835-L1871","documentation":"Thrown by normalizeDef() while initializing a $ZodObject whenever a value in def.shape fails the check `def.shape[k]?._zod?.traits?.has(\"$ZodType\")`. Every property of an object's shape must itself be a Zod schema instance carrying the $ZodType trait; passing a plain value, class, string, or non-schema object is rejected at construction time so that the object's parser can safely call _zod.run on each field.","triggerScenarios":"Building z.object({ foo: \"string\" }), z.object({ foo: String }), z.object({ foo: { min: 1 } }), z.object({ foo: null }), or programmatically spreading a non-schema map into the shape. Also occurs when a spread/merge utility forgets to wrap a field, or when a lazy import resolves to undefined and is used as a field.","commonSituations":"Typing field values as native constructors (String, Number) instead of z.string()/z.number(); passing raw regex or plain option objects; circular imports that yield undefined at module-eval time; dynamic shape construction from external config without wrapping values in z.unknown() or similar.","solutions":["Wrap every field value in a Zod schema (z.string(), z.number(), z.unknown(), etc.).","If building the shape dynamically, guard each entry: if (!value?._zod?.traits?.has(\"$ZodType\")) shape[k] = z.unknown();","Check for undefined caused by circular imports — reorder imports or use z.lazy().","Run a typecheck (tsc); the object() overload signature will usually flag mistyped fields before runtime."],"exampleFix":"// before\nconst Schema = z.object({ name: \"string\", age: Number });\n// after\nconst Schema = z.object({ name: z.string(), age: z.number() });","handlingStrategy":"type-guard","validationCode":"function buildObject(shape: Record<string, unknown>) {\n  const safe: Record<string, z.ZodType> = {};\n  for (const [k, v] of Object.entries(shape)) {\n    safe[k] = isZodSchema(v) ? v : z.unknown();\n  }\n  return z.object(safe);\n}","typeGuard":"function isZodSchema(v: unknown): v is z.ZodType {\n  return !!v && typeof v === \"object\" && (v as any)?._zod?.traits?.has(\"$ZodType\") === true;\n}","tryCatchPattern":"try {\n  return z.object(shape as Record<string, z.ZodType>);\n} catch (e) {\n  throw new Error(`Object shape invalid: ${(e as Error).message}. Ensure every field is a Zod schema.`);\n}","preventionTips":["Always wrap field values with z.* factories.","For dynamic shapes, type the input as Record<string, z.ZodType> so tsc catches mistakes.","Watch for undefined from circular imports — use z.lazy() if needed."],"tags":["object","schema-construction","shape","type-guard"],"backgroundTag":null,"analyzedSha":"2d90846af918af9602e088812d63a035d47cdbe4","analyzedAt":"2026-08-11T01:21:44.015Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-22T11:17:16.035Z"}