{"record":{"id":"436ad20fd9b17ca5","repo":"pydantic/monty","slug":"object-property-type-type-mismatch-expect-value-to-be-object","errorCode":null,"errorMessage":"Object property 'type' type mismatch. Expect value to be Object, but received ${jsType(object.type)}","messagePattern":"Object property 'type' type mismatch\\. Expect value to be Object, but received (.+?)","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"crates/monty-js/ts/worker/value.ts","lineNumber":178,"sourceCode":"    throw new TypeError(`Monty${typeName} timezoneName requires offsetSeconds`)\n  }\n  return aware\n    ? {\n        offsetSeconds: Number(object.offsetSeconds),\n        ...(typeof object.timezoneName === 'string' ? { timezoneName: object.timezoneName } : {}),\n      }\n    : {}\n}\n\n/**\n * Validates and converts a host `ClassInstance` marker (same shape the napi\n * path produces: `attrs` as ordered `[name, value]` pairs, uuids as\n * strings). Validation messages mirror napi's so both transports fail\n * malformed markers alike.\n */\nfunction pushClassInstance(object: Record<string, unknown>, nodes: ValueNode[]): ValueNode {\n  if (typeof object.type !== 'object' || object.type === null) {\n    throw new TypeError(\n      `Object property 'type' type mismatch. Expect value to be Object, but received ${jsType(object.type)}`,\n    )\n  }\n  if (!Array.isArray(object.attrs)) {\n    throw new TypeError(\n      `Object property 'attrs' type mismatch. Expect value to be Array, but received ${jsType(object.attrs)}`,\n    )\n  }\n  const pairs: [unknown, unknown][] = []\n  for (const pair of object.attrs as unknown[]) {\n    if (!Array.isArray(pair)) throw new TypeError('ClassInstance attrs entries must be [name, value] pairs')\n    if (typeof pair[0] !== 'string') throw new TypeError('ClassInstance attr name must be a string')\n    if (!(1 in pair)) throw new TypeError('ClassInstance attr value missing')\n    pairs.push([pair[0], pair[1]])\n  }\n  const classTypeNode = pushClassType(object.type as Record<string, unknown>, nodes)\n  const classTypeIndex = nodes.length\n  nodes.push({ tag: 'class-type', val: classTypeNode })","sourceCodeStart":160,"sourceCodeEnd":196,"githubUrl":"https://github.com/pydantic/monty/blob/adc986b362e3961f407868cb118a99fe831b9e61/crates/monty-js/ts/worker/value.ts#L160-L196","documentation":"pushClassInstance validates ClassInstance marker objects: the `type` property must be an object (the class-type marker describing the instance's class). This TypeError is thrown when `type` is a primitive, array-of-wrong-shape, or null, mirroring napi's validation so both transports fail identically on malformed markers.","triggerScenarios":"Passing a ClassInstance marker whose `type` is a string name instead of the nested class-type object (e.g. { marker: 'ClassInstance', type: 'MyClass', attrs: [...] }); JSON transformations that flatten `type` to its name; hand-built class instance inputs.","commonSituations":"Manual construction of class instance values for session inputs; a serializer that replaced the nested type object with the class name; partial deserialization of values received from a different transport.","solutions":["Provide the full nested class-type object as `type`: { marker: 'ClassType', name: 'MyClass', attrs: [...], ... } as produced by the runtime","Wrap value in typeof checks before passing: if (value && typeof value.type === 'object' && value.type !== null)","Pass values originally returned by the runtime rather than re-creating them"],"exampleFix":"// before\n{ marker: 'ClassInstance', type: 'Point', attrs: [] }\n// after\n{ marker: 'ClassInstance', type: { marker: 'ClassType', name: 'Point', attrs: [] }, attrs: [] }","handlingStrategy":"type-guard","validationCode":"function assertClassInstance(o: unknown): void {\n  const m = o as Record<string, unknown>\n  if (typeof m.type !== 'object' || m.type === null) throw new Error('ClassInstance.type must be an object')\n  if (!Array.isArray(m.attrs)) throw new Error('ClassInstance.attrs must be an array')\n}","typeGuard":"const isClassInstance = (v: unknown): v is { type: Record<string, unknown>; attrs: [string, unknown][] } =>\n  typeof v === 'object' && v !== null && typeof (v as any).type === 'object' && (v as any).type !== null && Array.isArray((v as any).attrs)","tryCatchPattern":"try {\n  return pushClassInstance(object, nodes)\n} catch (e) {\n  if (e instanceof TypeError && e.message.includes(\"property 'type' type mismatch\")) {\n    throw new Error('Malformed ClassInstance marker: nested class-type object required')\n  }\n  throw e\n}","preventionTips":["Keep the nested class-type object intact; never replace it with the class name string","Avoid transformations that flatten nested marker objects","Pass runtime-produced values through unchanged"],"tags":["typescript","validation","class-instance","value-conversion"],"backgroundTag":"type-mismatch","analyzedSha":"adc986b362e3961f407868cb118a99fe831b9e61","analyzedAt":"2026-09-13T19:19:18.698Z","contentChangedAt":"2026-09-13T19:19:18.698Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}