gleam-lang/gleam · error
is not a built-in type.
Error message
{name} is not a built-in type. What it means
The TypeScript prelude printer (`print_prelude_type`) maps built-in Gleam types (String, Int, Float, Bool, List, Result, BitArray, UtfCodepoint, etc.) to their TypeScript prelude equivalents. Any other type name reaching it is a compiler error, so it panics with the offending name.
Solutions
- Check the panic message for the type name and add a matching arm in `print_prelude_type` (compiler development).
- Ensure programmer-defined types go through the named-type printing path, not the prelude path.
- If triggered by ordinary user code, file a Gleam compiler bug with the reported type name.
Example fix
// before (in print_prelude_type)
name => panic!("{name} is not a built-in type.")
// after (during development of a new builtin)
"MyNewType" => Ok("MyNewType".to_string()),
name => panic!("{name} is not a built-in type.") Defensive patterns
Strategy: validation
Validate before calling
// route only built-ins through prelude printing
const BUILTINS: &[&str] = &["Int","Float","String","Bool","List","Result","BitArray","UtfCodepoint"];
if !BUILTINS.contains(&name.as_str()) {
return print_named_type(name); // named path instead of prelude
} Type guard
fn is_builtin_type(name: &str) -> bool {
matches!(name, "Int" | "Float" | "String" | "Bool" | "List" | "Result" | "BitArray" | "UtfCodepoint")
} Try / catch
match std::panic::catch_unwind(|| print_prelude_type(t)) {
Ok(s) => s,
Err(_) => fallback_to_named_type_printing(t),
} Prevention
- Ensure user-defined types use the named-type printing path.
- When adding a language built-in, update print_prelude_type in typescript.rs in the same change.
- Capture the type name from the panic message to speed up bug reports.
When it happens
Trigger: A type whose name is not a recognized built-in is printed as a prelude type — typically when a new built-in type is added to the core language but not registered in `typescript.rs`, or when internals pass a non-builtin type to prelude printing.
Common situations: Gleam compiler development adding language built-ins; tooling invoking the TypeScript printer with custom/core types it wasn't designed for.
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
- case with no subjects
- Custom type constructor exist for type
- Custom type constructor must have custom type kind
- Invalid bit array segment type reached code generation
- invalid constants should not reach code generation
AI-assisted analysis of gleam-lang/gleam@15b07c7830 (2026-09-14).
Data as JSON: /api/errors/f71a96d56452b92a.
Report an issue: GitHub.
Appendix: source
Thrown at compiler-core/src/javascript/typescript.rs:1181
)
]
}
"Result" => {
self.tracker.prelude_used = true;
docvec![
arena,
UNDERSCORE_DOT_RESULT_DOCUMENT,
wrap_generic_arguments(
arena,
arguments
.iter()
.map(|x| self.do_print(arena, x, generic_printing))
)
]
}
// Getting here should mean we either forgot a built-in type or there is a
// compiler error
name => panic!("{name} is not a built-in type."),
}
}
/// Prints a "named" programmer-defined Gleam type into the TypeScript
/// equivalent.
///
fn print_type_app(
&mut self,
arena: &'doc DocumentArena<'a, 'doc>,
name: &str,
arguments: &[Arc<Type>],
module: &str,
generic_printing: GenericPrinting<'_>,
) -> Document<'a, 'doc> {
let name = eco_format!("{}$", ts_safe_type_name(name.to_string()));
let name = match module == self.module.name {
true => name.to_doc(arena),
false => {View on GitHub (pinned to 15b07c7830)