{"record":{"id":"a4eead5478eb1497","repo":"colinhacks/zod","slug":"invalid-input-to-safeextend-expected-a-plain-obje","errorCode":null,"errorMessage":"Invalid input to safeExtend: expected a plain object","messagePattern":"Invalid input to safeExtend: expected a plain object","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/zod/src/v4/core/util.ts","lineNumber":689,"sourceCode":"      if (Object.getOwnPropertyDescriptor(existingShape, key) !== undefined) {\n        throw new Error(\"Cannot overwrite keys on object schemas containing refinements. Use `.safeExtend()` instead.\");\n      }\n    }\n  }\n\n  const def = mergeDefs(schema._zod.def, {\n    get shape() {\n      const _shape = { ...schema._zod.def.shape, ...shape };\n      assignProp(this, \"shape\", _shape); // self-caching\n      return _shape;\n    },\n  });\n  return clone(schema, def) as any;\n}\n\nexport function safeExtend(schema: schemas.$ZodObject, shape: schemas.$ZodShape): any {\n  if (!isPlainObject(shape)) {\n    throw new Error(\"Invalid input to safeExtend: expected a plain object\");\n  }\n  const def = mergeDefs(schema._zod.def, {\n    get shape() {\n      const _shape = { ...schema._zod.def.shape, ...shape };\n      assignProp(this, \"shape\", _shape); // self-caching\n      return _shape;\n    },\n  });\n  return clone(schema, def) as any;\n}\n\nexport function merge(a: schemas.$ZodObject, b: schemas.$ZodObject): any {\n  if (a._zod.def.checks?.length) {\n    throw new Error(\".merge() cannot be used on object schemas containing refinements. Use .safeExtend() instead.\");\n  }\n  const def = mergeDefs(a._zod.def, {\n    get shape() {\n      const _shape = { ...a._zod.def.shape, ...b._zod.def.shape };","sourceCodeStart":671,"sourceCodeEnd":707,"githubUrl":"https://github.com/colinhacks/zod/blob/2d90846af918af9602e088812d63a035d47cdbe4/packages/zod/src/v4/core/util.ts#L671-L707","documentation":"Thrown by safeExtend() when the shape argument fails the same isPlainObject() guard used by extend(). `.safeExtend()` is the refinement-safe variant of `.extend()` (it skips the check-overlap guard) but still requires a plain object literal as its shape argument. Class instances, arrays, Maps, null, and primitives are rejected.","triggerScenarios":"Calling `schema.safeExtend(classInstance)`, `schema.safeExtend([...])`, `schema.safeExtend(null)`, or any non-plain-object value. Same input contract as `.extend()`.","commonSituations":"Same as the extend() case: passing a typed Record, a schema object, an array of pairs, or a wrapper class instead of a literal shape map; migrating from `.extend()` to `.safeExtend()` without fixing an already-wrong argument type.","solutions":["Pass a plain object literal of key→schema pairs.","Coerce wrappers (Map, class, Record subclass) into a plain object via spread or Object.fromEntries before calling `.safeExtend()`.","Confirm the argument is not null, an array, or a primitive."],"exampleFix":"// before\nconst pairs: [string, z.ZodType][] = [['id', z.number()]];\nBase.safeExtend(pairs); // throws\n\n// after\nBase.safeExtend(Object.fromEntries(pairs));","handlingStrategy":"type-guard","validationCode":"function asSafeShape(shape: unknown): Record<string, z.ZodType> {\n  if (!isPlainShape(shape)) {\n    throw new TypeError('safeExtend() expects a plain object of key -> ZodType');\n  }\n  return shape as Record<string, z.ZodType>;\n}\n// base.safeExtend(asSafeShape(maybeShape));","typeGuard":"function isPlainShape(o: unknown): o is Record<string, z.ZodType> {\n  if (o === null || typeof o !== 'object' || Array.isArray(o)) return false;\n  const proto = Object.getPrototypeOf(o);\n  return proto === null || proto === Object.prototype;\n}","tryCatchPattern":null,"preventionTips":["Pass only plain object literals (or Object.fromEntries results) to `.safeExtend()`.","Reject arrays, Maps, and class instances at the boundary.","Reuse the same isPlainShape guard you use for `.extend()`."],"tags":["schema-transformation","safe-extend","type-validation","object-schema","zod-v4"],"backgroundTag":null,"analyzedSha":"2d90846af918af9602e088812d63a035d47cdbe4","analyzedAt":"2026-08-11T01:21:44.015Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-22T11:17:16.035Z"}