{"id":"457b7d4d748b39a5","repo":"sindresorhus/is","slug":"expected-value-which-is-plain-object-received-v","errorCode":null,"errorMessage":"Expected value which is `plain object`, received value of type `${is(value)}`.","messagePattern":"Expected value which is `plain object`, received value of type `(.+?)`\\.","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"source/index.ts","lineNumber":1836,"sourceCode":"\t\tthrow new TypeError(message ?? typeErrorMessage('Object', value));\n\t}\n}\n\nexport function assertObservable(value: unknown, message?: string): asserts value is ObservableLike {\n\tif (!isObservable(value)) {\n\t\tthrow new TypeError(message ?? typeErrorMessage('Observable', value));\n\t}\n}\n\nexport function assertOddInteger(value: number, message?: string): asserts value is number {\n\tif (!isOddInteger(value)) {\n\t\tthrow new TypeError(message ?? typeErrorMessage('odd integer', value));\n\t}\n}\n\nexport function assertPlainObject<Value = unknown>(value: unknown, message?: string): asserts value is Record<PropertyKey, Value> {\n\tif (!isPlainObject(value)) {\n\t\tthrow new TypeError(message ?? typeErrorMessage('plain object', value));\n\t}\n}\n\nexport function assertPositiveInteger(value: unknown, message?: string): asserts value is number {\n\tif (!isPositiveInteger(value)) {\n\t\tthrow new TypeError(message ?? typeErrorMessage('positive integer', value));\n\t}\n}\n\nexport function assertPositiveNumber(value: unknown, message?: string): asserts value is number {\n\tif (!isPositiveNumber(value)) {\n\t\tthrow new TypeError(message ?? typeErrorMessage('positive number', value));\n\t}\n}\n\nexport function assertPrimitive(value: unknown, message?: string): asserts value is Primitive {\n\tif (!isPrimitive(value)) {\n\t\tthrow new TypeError(message ?? typeErrorMessage('primitive', value));","sourceCodeStart":1818,"sourceCodeEnd":1854,"githubUrl":"https://github.com/sindresorhus/is/blob/7821031c66cdeb7256a0feb2d506535f9e84fcaf/source/index.ts#L1818-L1854","documentation":"Thrown by `assert.plainObject()` when the value is not a plain object — one created by `{}`, `new Object()`, or `Object.create(null)`. `isPlainObject` rejects arrays, class instances, Maps, Dates, functions, and primitives, which the looser `assert.object()` would accept. It narrows to `Record<PropertyKey, Value>` for safe key-value access.","triggerScenarios":"Calling `assert.plainObject(value)` with an array (a common surprise — arrays are objects but not plain), a class instance, a Map, null, undefined, or a value deserialized into a custom prototype.","commonSituations":"API returning a JSON array when an object was expected (or vice versa); passing a class-based model/ORM entity where a plain options bag is expected; structuredClone or cross-realm objects with unexpected prototypes; a Map used as a dictionary instead of a plain object.","solutions":["If the value is an array of entries or a Map, convert with `Object.fromEntries(value)` before asserting.","If class instances should be accepted, use the looser `assert.object()` instead.","Spread instances into plain objects at the boundary: `{...instance}` — noting this drops methods and prototype.","Check the API contract — a top-level JSON array vs object mismatch means the producer changed shape."],"exampleFix":"// before\nconst options = new Map([['depth', 2]]);\nassert.plainObject(options); // throws: received 'Map'\n// after\nconst options = Object.fromEntries(new Map([['depth', 2]]));\nassert.plainObject(options);","handlingStrategy":"type-guard","validationCode":"const proto = value === null || typeof value !== 'object' ? undefined : Object.getPrototypeOf(value);\nif (typeof value !== 'object' || value === null || (proto !== null && proto !== Object.prototype)) {\n  throw new TypeError('Expected a plain object (created by {} or Object.create(null))');\n}","typeGuard":"function isPlainObject(value: unknown): value is Record<string, unknown> {\n  if (typeof value !== 'object' || value === null) return false;\n  const proto = Object.getPrototypeOf(value);\n  return proto === null || proto === Object.prototype;\n}","tryCatchPattern":"try {\n  ow(value, ow.object.plain);\n} catch (error) {\n  if (error instanceof ArgumentError) {\n    throw new TypeError(`Options must be a plain object literal: ${error.message}`);\n  }\n  throw error;\n}","preventionTips":["Class instances, Maps, arrays, and Dates are objects but not plain objects — spread into a literal ({...instance}) if only data is needed","Objects crossing realm boundaries (iframes, vm, some structuredClone paths) can fail prototype identity checks","Pass options as object literals at the call site rather than reusing framework-constructed objects","JSON.parse output is plain and safe for plain-object parameters"],"tags":["type-check","assertion","plain-object","runtime-validation"],"analyzedSha":"7821031c66cdeb7256a0feb2d506535f9e84fcaf","analyzedAt":"2026-07-31T18:34:06.268Z","schemaVersion":2}