pydantic/monty · error · Error
value of type ${typeof value}
Error message
value of type ${typeof value} What it means
In the wasm worker path of `@pydantic/monty` (`crates/monty-js/ts/worker/value.ts:65`, in `pushValue`, used by `encodeValue` when marshaling inputs/results across the component boundary), a JavaScript value could not be mapped to any Monty value node. After all known `typeof` kinds are handled (and `symbol` throws its own TypeError), the final fallback throws this `unsupported` error naming the unresolved `typeof` — practically a defensive branch for values JS surfaces outside the enumerated set.
Source
Thrown at crates/monty-js/ts/worker/value.ts:65
} else if (value instanceof Uint8Array) {
node = { tag: 'bytes', val: value }
} else if (Array.isArray(value)) {
const items = Uint32Array.from(value.map((item) => pushValue(item, nodes)))
node = { tag: isTuple(value) ? 'tuple-value' : 'list-value', val: items }
} else if (value instanceof Map) {
node = { tag: 'dict', val: pushPairs([...value.entries()], nodes) }
} else if (value instanceof Set) {
node = { tag: 'set', val: Uint32Array.from([...value].map((item) => pushValue(item, nodes))) }
} else if (typeof value === 'function') {
node = { tag: 'function', val: { name: value.name ?? '' } }
} else if (typeof value === 'object') {
const object = value as Record<string, unknown>
node =
TYPE_MARKER in object ? pushMarked(object, nodes) : { tag: 'dict', val: pushPairs(Object.entries(object), nodes) }
} else if (typeof value === 'symbol') {
throw new TypeError('Cannot convert JS Symbol to Monty value')
} else {
throw unsupported(`value of type ${typeof value}`)
}
const index = nodes.length
nodes.push(node)
return index
}
/** Converts a `__monty_type__` marker into one semantic value node. */
function pushMarked(object: Record<string, unknown>, nodes: ValueNode[]): ValueNode {
switch (object[TYPE_MARKER]) {
case 'Ellipsis':
return { tag: 'ellipsis' }
case 'NotImplemented':
return { tag: 'not-implemented' }
case 'Date':
return {
tag: 'date',
val: { year: Number(object.year), month: Number(object.month), day: Number(object.day) },
}View on GitHub (pinned to adc986b362)
Solutions
- Log `typeof value` (and `Object.prototype.toString.call(value)`) on the offending input and convert it to a supported type before calling the session API.
- Wrap exotic objects in plain objects, arrays, strings, numbers, bigints, Maps, Sets, or `Uint8Array` — the types `pushValue` understands.
- Use the documented `__monty_type__` marker helpers for special Monty values (Ellipsis, Date, etc.) instead of host wrapper objects.
- If this fires for a standard JS value, report a bug: the fallback is expected to be unreachable for standard ECMAScript types.
Example fix
// before
await session.feedRun(code, { inputs: { handle: someExoticHostObject } });
// after
await session.feedRun(code, {
inputs: { handle: { id: someExoticHostObject.id, kind: String(someExoticHostObject.kind) } },
}); Defensive patterns
Strategy: type-guard
Validate before calling
// Ensure values crossing the Monty boundary are convertible
function isMontySafe(value: unknown): boolean {
return (
value === null || value === undefined ||
['boolean', 'number', 'bigint', 'string', 'function'].includes(typeof value) ||
value instanceof Uint8Array || value instanceof Map || value instanceof Set ||
Array.isArray(value) || (typeof value === 'object')
);
}
// Pre-check inputs: Object.values(inputs).every(isMontySafe) Type guard
function isConvertibleToMonty(value: unknown): value is
null | undefined | boolean | number | bigint | string | Uint8Array | Map<unknown, unknown> | Set<unknown> | unknown[] | Record<string, unknown> | Function {
return value === null || value === undefined || typeof value !== 'symbol';
} Try / catch
import { MontyError } from '@pydantic/monty';
try {
await session.feedRun(code, { inputs });
} catch (err) {
if (err instanceof MontyError && String(err.message).startsWith('unsupported: value of type')) {
console.error('Unconvertible input:', Object.values(inputs).map(v => typeof v));
}
throw err;
} Prevention
- Only pass plain JS data (objects, arrays, strings, numbers, bigints, Maps, Sets, Uint8Array) into Monty sessions and callbacks.
- Never pass Symbols; the converter rejects them explicitly — use strings as keys/names instead.
- Unwrap host wrapper objects (proxies, class instances with exotic behavior) into plain objects before crossing the boundary.
- Type inputs with the exported session input types so exotic values are caught at compile time.
When it happens
Trigger: Passing a value into `session.feedRun` inputs, a return value from an `externalLookup` function, or any host callback result that `encodeValue` cannot classify: not null/boolean/number/bigint/string/Uint8Array/Array/Map/Set/function/plain-object/marked object, and not a `symbol` (which gets its own TypeError). In practice this fires only for exotic `typeof` results outside ECMAScript's standard set (e.g. non-standard host/undocumented typeof values or a future JS typeof kind).
Common situations: Rare; usually seen when a custom class instance with an exotic proxy/undici-style wrapper or a host-provided exotic object flows into the drive loop, or when a JS engine/embedding reports a non-standard `typeof`. Standard JS values convert fine — plain objects become dicts, Maps/Sets/typed data all have dedicated branches.
Understand the failure class
Background: "is not a compatible type" / "cannot merge" errors: when a value's type doesn't match what the library requires — this error's family across 65 libraries.
Related errors
- Unknown Monty marker type: ${String(object[TYPE_MARKER])}
- ClassType attrs entries must be [name, value] pairs
- ClassType attr name must be a string
- ClassType attr value missing
- ${what} must be a canonical uuid string
AI-assisted analysis of pydantic/monty@adc986b362 (2026-09-13).
Data as JSON: /api/errors/734a6d43952b761a.
Report an issue: GitHub.