pydantic/monty · error · TypeError

raw Type markers are not accepted — pass the class through C

Error message

raw Type markers are not accepted — pass the class through ClassType(...)

What it means

A Type marker carrying a classType (a host-class marker) is only produced internally by the prepare walk; host code must pass classes through the ClassType(...) wrapper function instead. A raw one arriving at prepareInner is rejected with this TypeError, since it could be forged to impersonate a registered host class. Builtin Type markers (e.g. { value: 'int' }) carry no identity and pass through.

Source

Thrown at crates/monty-js/ts/classInstance.ts:545

  }
  if (value instanceof Set) {
    return walkSet(value, walk)
  }
  if (value instanceof Uint8Array) {
    return value
  }
  const marker = readTypeMarker(value)
  if (marker === 'ClassInstance') {
    // Identity-bearing markers are produced internally by this walk, never
    // held by host code (`restore` maps them to the original object or a
    // MontyClassProxy). One arriving here is forged — e.g. embedded
    // in attacker-controlled JSON to impersonate a registered instance.
    throw new TypeError('raw ClassInstance markers are not accepted — wrap the object in ClassInstance(...)')
  }
  if (marker === 'Type' && (value as { classType?: unknown }).classType !== undefined) {
    // Same reasoning for a host-class marker; builtin `Type` markers
    // (`{ value: 'int' }`) carry no identity and pass through.
    throw new TypeError('raw Type markers are not accepted — pass the class through ClassType(...)')
  }
  if (marker !== undefined) {
    return value
  }
  if (isPlainObject(value)) {
    return walkPlainObject(value as Record<string, unknown>, walk)
  }
  throw new TypeError(
    `Cannot convert ${constructorName(value)} instance to a Monty value — wrap it in ClassInstance(...)`,
  )
}

/**
 * Inbound walk over a sandbox value reaching the host: maps `ClassInstance`
 * markers to the original wrapped object when the id is in `store` (identity
 * preserved), else to a [`MontyClassProxy`] proxy with recursively
 * restored attrs; maps a host-class `Type` marker to the registered class
 * object the same way (an unregistered class stays a marker); recurses into

View on GitHub (pinned to adc986b362)

Solutions

  1. Pass the class itself through ClassType(MyClass) instead of a raw marker object
  2. Re-create the wrapper from the live class rather than caching wire-format output
  3. Sanitize untrusted JSON so marker-shaped objects never reach the sandbox boundary

Example fix

// before
session.feedRun('make(K)', { inputs: { K: { type: 'Type', classType: 'MyClass' } } });
// after
session.feedRun('make(K)', { inputs: { K: ClassType(MyClass) } });
Defensive patterns

Strategy: type-guard

Validate before calling

function looksLikeTypeMarker(v) {
  return typeof v === 'object' && v !== null && v.type === 'Type' && v.classType !== undefined;
}
if (looksLikeTypeMarker(inputs.K)) throw new Error('pass the class via ClassType(MyClass)');

Type guard

function isClassTypeWrapper(v) {
  return typeof v === 'function' || (typeof v === 'object' && v !== null && v.__montyIsClassType === true);
}

Try / catch

try {
  await session.feedRun(code, { inputs });
} catch (e) {
  if (e instanceof TypeError && e.message.includes('raw Type markers are not accepted')) {
    throw new Error('pass the class through ClassType(MyClass), not a marker object');
  }
  throw e;
}

Prevention

When it happens

Trigger: Passing a raw host-class Type marker object (round-tripped wire output or marker-shaped untrusted JSON) as an input, external-function result, or attribute where a class is expected, instead of calling ClassType(MyClass).

Common situations: Feeding back previously serialized wire values; passing class references extracted from restore() output; constructing marker-like objects by hand from documentation of the wire format.

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


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