pydantic/monty · error · TypeError

Cannot convert JS Symbol to Monty value

Error message

Cannot convert JS Symbol to Monty value

What it means

When converting JS inputs into Monty values, JavaScript `Symbol` has no Monty/Python counterpart the converter supports, so it is rejected explicitly with a `TypeError` while building the flat node arena. All other primitives (string, number, boolean, null, undefined, bigint, function) and plain objects/arrays are convertible; Symbols are not.

Source

Thrown at crates/monty-js/ts/worker/value.ts:63

  } else if (typeof value === 'string') {
    node = { tag: 'text', val: value }
  } 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',

View on GitHub (pinned to adc986b362)

Solutions

  1. Replace Symbol values with plain strings or another primitive before passing inputs: `String(sym)` won't help — use the symbol's description explicitly (`sym.description ?? ''`).
  2. Strip Symbol-valued properties from input objects (Symbols are also skipped by `JSON.stringify` — mirror that filtering).
  3. Use a dedicated sentinel string or enum value instead of a Symbol to communicate sentinel semantics to the sandboxed Python code.

Example fix

// before
await session.feedRun(code, { inputs: { key: Symbol('x') } }) // TypeError

// after
await session.feedRun(code, { inputs: { key: 'x' } })
Defensive patterns

Strategy: type-guard

Validate before calling

function assertConvertible(v: unknown): void {
  if (typeof v === 'symbol') throw new TypeError('Symbol inputs are not supported')
  if (v && typeof v === 'object') Object.values(v).forEach(assertConvertible)
}

Type guard

function isConvertible(v: unknown): boolean {
  if (typeof v === 'symbol') return false
  if (v && typeof v === 'object') return Object.values(v).every(isConvertible)
  return true
}

Try / catch

try {
  await session.feedRun(code, { inputs })
} catch (err) {
  if (err instanceof TypeError && err.message.includes('Symbol')) {
    await session.feedRun(code, { inputs: stripSymbols(inputs) })
  } else throw err
}

Prevention

When it happens

Trigger: Passing a Symbol (or an object containing a Symbol property value, e.g. in `inputs` or nested structures) to `feedRun`/`feed` so that `pushValue` walks into it: `inputs: { key: Symbol('x') }`.

Common situations: Using well-known Symbols (`Symbol.iterator`, `Symbol.asyncIterator`) or library sentinel Symbols as input values; accidentally forwarding a config object containing Symbol sentinels; serializing structures that use Symbols as private fields.

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


AI-assisted analysis of pydantic/monty@adc986b362 (2026-09-13). Data as JSON: /api/errors/671d603480c4cb83. Report an issue: GitHub.