{"record":{"id":"95f8b600ebaa720b","repo":"pydantic/monty","slug":"classinstance-attrs-entries-must-be-name-value-pairs","errorCode":null,"errorMessage":"ClassInstance attrs entries must be [name, value] pairs","messagePattern":"ClassInstance attrs entries must be \\[name, value\\] pairs","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"crates/monty-js/ts/worker/value.ts","lineNumber":189,"sourceCode":" * 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 })\n  return {\n    tag: 'class-instance',\n    val: {\n      classType: classTypeIndex,\n      instanceId: uuidString(object.instanceId, 'ClassInstance instanceId'),\n      attrs: pushPairs(pairs, nodes),\n    },\n  }\n}\n\n/** Builds a class-type node from the plain `classType` marker object,","sourceCodeStart":171,"sourceCodeEnd":207,"githubUrl":"https://github.com/pydantic/monty/blob/adc986b362e3961f407868cb118a99fe831b9e61/crates/monty-js/ts/worker/value.ts#L171-L207","documentation":"A validation guard in the wasm-worker value converter's `pushClassInstance`, which turns a host-supplied `ClassInstance` marker into flat value nodes. It fires when an entry of the marker's `attrs` array is not a `[name, value]` pair (wrong length or not an array). The marker shape must mirror what the napi path produces — ordered `[name, value]` pairs — so malformed host input is rejected here with a TypeError before it reaches the interpreter.","triggerScenarios":"attrs containing entries like {name: 'x', value: 1} objects instead of ['x', 1] arrays; attrs containing stray non-pair elements after manual splicing or filtering.","commonSituations":"Mapping attribute dictionaries entry-by-entry (Object.entries output must be used directly, but hand-rolled transforms may produce objects); copying attrs from another serialization format with different pair encoding.","solutions":["Ensure every attrs element is exactly a two-element array [stringName, value]","Use Object.entries(obj) directly, which already yields [key, value] arrays","Validate with attrs.every(Array.isArray) before passing"],"exampleFix":"// before\nattrs: [{ name: 'x', value: 1 }]\n// after\nattrs: [['x', 1]]","handlingStrategy":"validation","validationCode":"const validPairs = (attrs: unknown[]): boolean => attrs.every(a => Array.isArray(a) && a.length === 2)","typeGuard":"const isPair = (p: unknown): p is [string, unknown] => Array.isArray(p) && p.length === 2","tryCatchPattern":"try {\n  return pushClassInstance(object, nodes)\n} catch (e) {\n  if (e instanceof TypeError && e.message === 'ClassInstance attrs entries must be [name, value] pairs') {\n    // find offending entry for diagnostics, then rethrow with index\n  }\n  throw e\n}","preventionTips":["Build attrs exclusively with Object.entries or explicit tuple literals","Validate every attrs entry is an array before calling the API","Never mix pair encodings (objects vs arrays) in one attrs list"],"tags":["typescript","validation","class-instance","array"],"backgroundTag":"invalid-argument-format","analyzedSha":"adc986b362e3961f407868cb118a99fe831b9e61","analyzedAt":"2026-09-13T19:19:18.698Z","contentChangedAt":"2026-09-13T19:19:18.698Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}