diem/diem · error
Type {:?} is not allowed in scripts.
Error message
Type {:?} is not allowed in scripts. What it means
get_type_tag converts Move prover types into TypeTags for script ABI generation. Move's builtin domain types Num, Range, and EventStore only exist inside the prover/spec language and have no runtime representation in scripts, so encountering one is an unrecoverable mapping failure. The library bails with this message naming the offending type.
Source
Thrown at language/move-prover/abigen/src/abigen.rs:236
Ok(bytes)
}
}
}
fn get_type_tag(&self, ty0: &ty::Type) -> anyhow::Result<TypeTag> {
use ty::Type::*;
let tag = match ty0 {
Primitive(prim) => {
use ty::PrimitiveType::*;
match prim {
Bool => TypeTag::Bool,
U8 => TypeTag::U8,
U64 => TypeTag::U64,
U128 => TypeTag::U128,
Address => TypeTag::Address,
Signer => TypeTag::Signer,
Num | Range | EventStore => {
bail!("Type {:?} is not allowed in scripts.", ty0)
}
}
}
Vector(ty) => {
let tag = self.get_type_tag(ty)?;
TypeTag::Vector(Box::new(tag))
}
Tuple(_)
| Struct(_, _, _)
| TypeParameter(_)
| Fun(_, _)
| TypeDomain(_)
| ResourceDomain(..)
| Error
| Var(_)
| Reference(_, _) => bail!("Type {:?} is not allowed in scripts.", ty0),
};
Ok(tag)View on GitHub (pinned to fc4714a8ea)
Solutions
- Remove spec-only builtin types (Num, Range, EventStore) from the function's runtime signature
- Replace them with concrete runtime types such as u64/u128 for numeric spec types
- Move spec-only logic into `spec` blocks or `intrinsic`-annotated helpers not part of the script ABI
- Re-run abigen after cleaning the signature
Example fix
// before
public fun f(x: num): range { ... }
// after
public fun f(x: u64): u64 { ... } Defensive patterns
Strategy: validation
Validate before calling
fn is_script_safe(ty: &Type) -> bool {
use Type::*;
!matches!(ty, Num | Range | EventStore)
}
// check every param/return before generate_abi_for_function Type guard
fn is_runtime_builtin(ty: &Type) -> bool {
matches!(ty, Type::U8 | Type::U64 | Type::U128 | Type::Address | Type::Signer)
} Try / catch
match abigen::get_type_tag(&ty) {
Ok(tag) => tag,
Err(e) if e.to_string().contains("not allowed in scripts") => {
eprintln!("function uses spec-only types; skipping ABI generation");
return None;
}
Err(e) => return Err(e),
} Prevention
- Keep spec-only builtins (Num, Range, EventStore) inside spec blocks, never in runtime signatures
- Use u64/u128 for numeric spec reasoning instead of `num` in public functions
- Review public function signatures before running abigen
- Filter internal/spec functions out of the ABI generation input
When it happens
Trigger: generate_abi_for_function encountering a function parameter or return type that is (or contains) the spec-only builtin Num, Range, or EventStore type; get_type_tag recursing into a Vector element of those types.
Common situations: Running abigen on a module whose public functions use specification-only types (e.g. a `range` or `num` builtin from the Move spec language) as if they were runtime values; accidentally exposing spec internals through script-visible signatures.
Related errors
- internal error: entered unreachable code
- ICE type mismatch on index lookup
- ICE type constraints failed {}:{}-{}
- ICE kind not expanded: {:#?}
- Script visibility not supported yet
AI-assisted analysis of diem/diem@fc4714a8ea (2026-09-04).
Data as JSON: /api/errors/29b367aa580fe109.
Report an issue: GitHub.