pydantic/monty · error · TypeError
ClassType attrs must be an array of [name, value] pairs
Error message
ClassType attrs must be an array of [name, value] pairs
What it means
pushClassType requires a ClassType marker's `attrs` to be an array of [name, value] pairs. A missing or non-array attrs is treated as a forged or malformed marker (not an empty class) and rejected with this TypeError, matching the native binding's contract.
Source
Thrown at crates/monty-js/ts/worker/value.ts:217
val: {
classType: classTypeIndex,
instanceId: uuidString(object.instanceId, 'ClassInstance instanceId'),
attrs: pushPairs(pairs, nodes),
},
}
}
/** Builds a class-type node from the plain `classType` marker object,
* appending its eager attr nodes to the arena. */
function pushClassType(
object: Record<string, unknown>,
nodes: ValueNode[],
): Extract<ValueNode, { tag: 'class-type' }>['val'] {
// Require an array like the native binding does, so both transports
// enforce the same marker contract (a missing `attrs` is a forged or
// malformed marker, not an empty attribute list).
if (!Array.isArray(object.attrs)) {
throw new TypeError('ClassType attrs must be an array of [name, value] pairs')
}
const attrPairs: [unknown, unknown][] = []
for (const pair of object.attrs as unknown[]) {
if (!Array.isArray(pair)) throw new TypeError('ClassType attrs entries must be [name, value] pairs')
if (typeof pair[0] !== 'string') throw new TypeError('ClassType attr name must be a string')
if (!(1 in pair)) throw new TypeError('ClassType attr value missing')
attrPairs.push([pair[0], pair[1]])
}
return {
name: String(object.name),
id: uuidString(object.id, 'ClassType id'),
hostDefined: object.hostDefined === true,
isDataclass: object.isDataclass === true,
attrs: pushPairs(attrPairs, nodes),
}
}
/** A canonical uuid string is required for identities crossing the wire. */View on GitHub (pinned to adc986b362)
Solutions
- Include attrs: [] explicitly even when the class has no attributes
- Ensure attrs is an array of [stringName, value] pairs
- Validate with Array.isArray(marker.attrs) before passing the marker
Example fix
// before
{ marker: 'ClassType', name: 'Empty' } // attrs missing
// after
{ marker: 'ClassType', name: 'Empty', attrs: [] } Defensive patterns
Strategy: validation
Validate before calling
const assertClassType = (o: Record<string, unknown>): void => {
if (!Array.isArray(o.attrs)) throw new Error('ClassType.attrs must be an array of [name, value] pairs')
if (!o.attrs.every(p => Array.isArray(p) && typeof p[0] === 'string' && 1 in p)) throw new Error('Bad ClassType attrs pair')
} Type guard
const isClassType = (v: unknown): v is { name: string; attrs: [string, unknown][] } =>
typeof v === 'object' && v !== null && typeof (v as any).name === 'string' && Array.isArray((v as any).attrs) Try / catch
try {
return pushClassType(object, nodes)
} catch (e) {
if (e instanceof TypeError && e.message.startsWith('ClassType attrs must be an array')) {
throw new Error('Forged or incomplete ClassType marker: attrs array required')
}
throw e
} Prevention
- Always include attrs (use [] for attribute-less classes), never omit the key
- Keep markers in their runtime-produced shape; don't trim fields for payload size
- Validate marker shape once at your transport boundary before calling the worker API
When it happens
Trigger: Passing a ClassType marker without an attrs key; attrs as an object map instead of an array of pairs; markers reconstructed from partial data where class attributes were dropped.
Common situations: Hand-building class type descriptors for typed inputs; trimming marker payloads and accidentally removing attrs; converting markers from a format where empty attrs is null.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- Object property 'type' type mismatch. Expect value to be Obj
- Max input depth exceeded
- raw Type markers are not accepted — pass the class through C
- ClassInstance marker instanceId must be a uuid string
- ${field} must be 'all', undefined or a list/Set of names, go
AI-assisted analysis of pydantic/monty@adc986b362 (2026-09-13).
Data as JSON: /api/errors/9ab134d445c9877d.
Report an issue: GitHub.