BoundaryML/baml · error
ntypeargs fits in u16
Error message
ntypeargs fits in u16
What it means
When emitting MakeVirtualBoundMethod, the count of type_args for the virtual bound method must fit the instruction's u16 ntypeargs field; try_from().expect enforces this as a compiler-internal invariant. Surpassing 65535 type args indicates a bug, not a user-facing condition.
Source
Thrown at baml_language/crates/baml_compiler2_emit/src/emit.rs:1963
{
// Stack layout mirrors `VirtualCall`: receiver, then the method-level
// type args, then the interface type (each resolved against the frame
// by `LoadType`), then the method name — the opcode pops in reverse.
self.emit_operand_pull(receiver);
for template in type_args {
let const_idx =
self.add_constant(ConstValue::Type(bex_vm_types::anchor_template(template)));
let inst = self.emit(Instruction::LoadType(const_idx));
self.set_operand(inst, OperandMeta::Const(template.to_string()));
}
let iface_const = self.add_constant(ConstValue::Type(bex_vm_types::anchor_template(
&iface.to_template(),
)));
let inst = self.emit(Instruction::LoadType(iface_const));
self.set_operand(inst, OperandMeta::Const(iface.to_string()));
self.emit_constant(&Constant::String(method.clone()));
let inst = self.emit(Instruction::MakeVirtualBoundMethod {
ntypeargs: u16::try_from(type_args.len()).expect("ntypeargs fits in u16"),
});
self.set_operand(inst, OperandMeta::Callable(method.clone()));
return;
}
if let Rvalue::MakeVirtualFunction {
self_ty,
iface,
method,
type_args,
} = rvalue
{
// Stack layout mirrors `MakeVirtualBoundMethod` with the `Self`
// TYPE in the receiver's slot: `Self`, then the method-level type
// args (already `Object::Type` OPERANDS — every one of them a
// `LoadType` temp, a scoped `type T = …` slot included),
// then the interface type, then the method name — the opcode pops
// in reverse.
let self_const =View on GitHub (pinned to bd85ce9dee)
Solutions
- File a compiler bug with the minimizing repro; reduce the number of type arguments on the virtual bound method
- Inspect type_args construction for accidental duplication in the emitter
- Refactor the interface/method into smaller parameterized pieces as a workaround
Defensive patterns
Strategy: try-catch
Try / catch
let ntypeargs = u16::try_from(type_args.len())
.map_err(|_| anyhow!("too many type args for MakeVirtualBoundMethod: {}", type_args.len()))?; Prevention
- Report any occurrence as a compiler bug with a repro
- Limit generated virtual-method type-argument counts
- Check type_args assembly for duplicated entries
- Add emitter tests covering large type-arg lists
When it happens
Trigger: emit.rs emitting MakeVirtualBoundMethod for an interface/type-args list longer than u16::MAX (type_args.len() > 65535).
Common situations: Only via compiler bugs or enormous generated type-argument lists; unreachable in realistic hand-written code.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- type_arg_templates count fits in u16
- duplicate compilation unit for `{}`
- interface body has no Pass-1 slot: {item}
- {what}: {item}
- undefined global item: {name_str}
AI-assisted analysis of BoundaryML/baml@bd85ce9dee (2026-09-12).
Data as JSON: /api/errors/da1736940fd4cc13.
Report an issue: GitHub.