pydantic/monty · error · TypeError
cannot instantiate host class '${this.getName()}'
Error message
cannot instantiate host class '${this.getName()}' What it means
ClassType never lets sandbox code instantiate a host class by default; construction is allowed only when the wrapper was created with `init: true`. This TypeError is raised in ClassType.construct (reached via __call__ when sandbox code calls the class) whenever the init gate is not exactly true — it is a purely host-side policy check applied on every construction request.
Source
Thrown at crates/monty-js/ts/classInstance.ts:325
/** Routes `__call__` (construction) to [`construct`](ClassType.construct);
* every other name is a static-method call gated by `allowedMethods`. */
override callMethod(name: string, args: unknown[], kwargs: Record<string, unknown>): unknown {
if (name === '__call__') {
return this.construct(args, kwargs)
}
return super.callMethod(name, args, kwargs)
}
/**
* Constructs an instance for the sandbox, checking the `init` policy —
* a purely host-side gate that never crosses the wire. JS constructors
* have no keyword arguments, so a non-empty `kwargs` is appended as a
* final options bag, matching [`ClassInstance.callMethod`].
*/
construct(args: unknown[], kwargs: Record<string, unknown>): ClassInstance {
if (this.options.init !== true) {
throw new TypeError(`cannot instantiate host class '${this.getName()}'`)
}
const callArgs = Object.keys(kwargs).length > 0 ? [...args, kwargs] : args
return this.instanceWrapper(new this.classType(...(callArgs as never[])))
}
/** Wraps a constructed instance with the `instance*` policies. The instance
* carries this wrapper as its `classType`, so its class keeps this
* wrapper's `id`, `name` and eager class attrs; a constructor that returns
* an object of another class gets that class's default wrapper instead.
* Override to customize how constructed instances are exposed. */
instanceWrapper(instance: object): ClassInstance {
const { instanceEagerAttrs, instanceLazyAttrs, instanceAllowedMethods, convertValue } = this.options
const ownClass = classOf(instance) === this.classType
return new ClassInstance(instance, {
eagerAttrs: instanceEagerAttrs,
lazyAttrs: instanceLazyAttrs,
allowedMethods: instanceAllowedMethods,
convertValue,View on GitHub (pinned to adc986b362)
Solutions
- Create the wrapper with `new ClassType(Point, { init: true })` to allow construction.
- If the class should not be constructible, remove or guard the `Point(...)` call in the sandbox code.
- Grant instance-level access a different way: construct the instance host-side and pass it as a ClassInstance input.
- Pair init: true with instance* policies (instanceEagerAttrs, instanceLazyAttrs, instanceAllowedMethods) to control what constructed instances expose.
Example fix
// before
inputs: { Point: new ClassType(Point) } // sandbox: Point(1, 2) → TypeError
// after
inputs: { Point: new ClassType(Point, { init: true, instanceEagerAttrs: 'all' }) } Defensive patterns
Strategy: try-catch
Validate before calling
function canInstantiate(type: ClassType): boolean {
if (type.options.init !== true) {
throw new TypeError(`enable init: true on the ClassType for '${type.getName()}' before sandbox use`)
}
return true
} Type guard
function allowsInit(type: ClassType): boolean {
return type.options.init === true
} Try / catch
try {
await session.feedRun('p = Point(1, 2)', { inputs: { Point } })
} catch (e) {
if (e instanceof TypeError && /cannot instantiate host class/.test(e.message)) {
const name = /'([^']+)'/.exec(e.message)?.[1]
throw new TypeError(`set init: true on the ClassType wrapper for '${name}'`)
} else throw e
} Prevention
- Every ClassType you expect sandbox code to call must be created with init: true
- Default is no construction — audit wrapper configs when sandbox code grows a constructor call
- Pair init: true with instance* policies to keep constructed instances tightly scoped
- init is host-side only; it is not part of the wire contract, so re-check it when reusing wrappers across sessions
When it happens
Trigger: Sandbox code runs `Point(1, 2)` (a `__call__` on the class wrapper) while the host registered the class with `new ClassType(Point)` or `new ClassType(Point, { init: false })` — i.e. init omitted or explicitly false.
Common situations: Forgetting init: true when granting a class you intend sandbox code to construct; a policy change tightening defaults; sandbox code evolved to construct a class the host only meant to expose for static methods/constants.
Related errors
- monty binary not found at binaryPath: ${explicit}
- notCallableMessage(method)
- classType does not match the instance's class
- pass name on the ClassType wrapper, not alongside classType
- ${field} must be 'all', undefined or a list/Set of names, go
AI-assisted analysis of pydantic/monty@adc986b362 (2026-09-13).
Data as JSON: /api/errors/586d0cd2ac1e3bea.
Report an issue: GitHub.