pydantic/monty · error · TypeError
ClassInstance attr name must be a string
Error message
ClassInstance attr name must be a string
What it means
Validation guard in the wasm-worker `pushClassInstance` converter: fires when a `ClassInstance` marker's `attrs` entry contains a first element (the attribute name) that is not a string. Attribute names must be Python identifier strings, matching the napi transport's encoding, so the host passed a malformed marker and gets a TypeError before serialization.
Source
Thrown at crates/monty-js/ts/worker/value.ts:190
* path produces: `attrs` as ordered `[name, value]` pairs, uuids as
* strings). Validation messages mirror napi's so both transports fail
* malformed markers alike.
*/
function pushClassInstance(object: Record<string, unknown>, nodes: ValueNode[]): ValueNode {
if (typeof object.type !== 'object' || object.type === null) {
throw new TypeError(
`Object property 'type' type mismatch. Expect value to be Object, but received ${jsType(object.type)}`,
)
}
if (!Array.isArray(object.attrs)) {
throw new TypeError(
`Object property 'attrs' type mismatch. Expect value to be Array, but received ${jsType(object.attrs)}`,
)
}
const pairs: [unknown, unknown][] = []
for (const pair of object.attrs as unknown[]) {
if (!Array.isArray(pair)) throw new TypeError('ClassInstance attrs entries must be [name, value] pairs')
if (typeof pair[0] !== 'string') throw new TypeError('ClassInstance attr name must be a string')
if (!(1 in pair)) throw new TypeError('ClassInstance attr value missing')
pairs.push([pair[0], pair[1]])
}
const classTypeNode = pushClassType(object.type as Record<string, unknown>, nodes)
const classTypeIndex = nodes.length
nodes.push({ tag: 'class-type', val: classTypeNode })
return {
tag: 'class-instance',
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. */View on GitHub (pinned to adc986b362)
Solutions
- Convert the name element with String(name) before building the pair
- Validate typeof pair[0] === 'string' for every pair before passing the marker
- Keep attribute names as strings end to end
Example fix
// before attrs: [[42, 'answer']] // after attrs: [['answer', 42]]
Defensive patterns
Strategy: validation
Validate before calling
const namesAreStrings = (attrs: unknown[]): boolean => attrs.every(a => Array.isArray(a) && typeof a[0] === 'string')
Type guard
const hasStringName = (p: unknown): p is [string, unknown] => Array.isArray(p) && typeof p[0] === 'string'
Try / catch
try {
return pushClassInstance(object, nodes)
} catch (e) {
if (e instanceof TypeError && e.message === 'ClassInstance attr name must be a string') {
object.attrs = (object.attrs as unknown[]).map(([n, v]) => [String(n), v]) // coerce then retry
return pushClassInstance(object, nodes)
}
throw e
} Prevention
- Coerce attribute names to strings at the source (String(key))
- Use Map→Object.entries pipelines that guarantee string keys
- Validate names with typeof before passing markers
When it happens
Trigger: attrs pairs like [1, 'one'] using numeric keys; attribute names derived from symbols or numbers without conversion; pairs built as [key, value] where key came from a numeric source.
Common situations: Converting a Map with non-string keys to attrs pairs; indexing artifacts where attribute positions were used instead of names.
Understand the failure class
Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.
Related errors
- ClassInstance marker instanceId must be a uuid string
- Object property 'type' type mismatch. Expect value to be Obj
- Object property 'attrs' type mismatch. Expect value to be Ar
- ClassInstance attrs entries must be [name, value] pairs
- ClassInstance attr value missing
AI-assisted analysis of pydantic/monty@adc986b362 (2026-09-13).
Data as JSON: /api/errors/b02632e33b587fe8.
Report an issue: GitHub.