pydantic/monty · error · TypeError
ClassType attrs entries must be [name, value] pairs
Error message
ClassType attrs entries must be [name, value] pairs
What it means
pushClassType in the wasm worker value codec converts a host-side ClassType marker object into a flat arena node before sending it to the sandbox. Each entry of object.attrs must be an array of exactly a name and a value. This TypeError is thrown when an attrs entry is not an array at all (e.g. an object, string, or null).
Source
Thrown at crates/monty-js/ts/worker/value.ts:221
},
}
}
/** 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. */
function uuidString(value: unknown, what: string): string {
if (
typeof value !== 'string' ||
!/^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$/.test(value)View on GitHub (pinned to adc986b362)
Solutions
- Inspect the failing attrs element and replace it with a two-element array `[name, value]`, e.g. `{ name: 'x', value: 1 }` becomes `['x', 1]`.
- Log the full marker object before the call to spot which attrs entry is malformed.
- If migrating from an object-keyed attrs form, map with `Object.entries(attrs)` which yields [name, value] pairs directly.
- Ensure no entry is null/undefined by validating `attrs.every(Array.isArray)` before the call.
Example fix
// before
node.attrs = [{ name: 'x', value: 1 }]
// after
node.attrs = [['x', 1]] Defensive patterns
Strategy: validation
Validate before calling
function validClassMarker(m) {
return m && m[TYPE_MARKER] === 'ClassType'
&& Array.isArray(m.attrs)
&& m.attrs.every(p => Array.isArray(p));
}
if (!validClassMarker(marker)) throw new TypeError('bad ClassType marker'); Type guard
const isAttrPair = (p: unknown): p is [string, unknown] => Array.isArray(p) && typeof p[0] === 'string' && 1 in p;
Try / catch
try {
await session.feedRun(code, { inputs: { cls: marker } });
} catch (e) {
if (e instanceof TypeError && e.message.includes('ClassType attrs entries')) {
marker.attrs = marker.attrs.filter(Array.isArray);
} else throw e;
} Prevention
- Always build attrs with Object.entries() so pairs are [name, value] arrays
- Validate marker shape with a type guard before every feedRun call
- Never hand-write attrs as {name, value} objects — the wire format is tuple pairs
- Add a unit test round-tripping each marker shape you construct
When it happens
Trigger: Calling a Monty value-conversion API that receives a `{ [TYPE_MARKER]: 'ClassType', attrs: [...] }` marker where some element of attrs is not an array — e.g. `attrs: [{ name: 'x', value: 1 }]`, `attrs: ['x', 1]`, or an entry of `null`.
Common situations: Hand-building ClassType markers instead of using the library's helpers; JS objects accidentally passed where tuple-style arrays are expected; refactors that changed the attrs shape from key/value objects to [name, value] pairs.
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
Related errors
- ClassType attr name must be a string
- ClassType attr value missing
- Unknown Monty marker type: ${String(object[TYPE_MARKER])}
- ${what} must be a canonical uuid string
- MontyFileHandle path must be a string
AI-assisted analysis of pydantic/monty@adc986b362 (2026-09-13).
Data as JSON: /api/errors/f8c44d368688da7b.
Report an issue: GitHub.