Type diagnostics come from checking item signatures (types, constants, aliases, bounds) and from type inference of function and scene bodies: mismatched types, bounded-integer arithmetic, conversions, fields and methods, calls, patterns and match exhaustiveness. Every code here is an error except W2039.
E2001 mismatched-types
Error. A value’s type differs from the type its context expects, such as a let annotation, a return type or a function argument.
fn mismatch() -> bool { let n: u32 = true; 5}Fix: make the value match the expected type, e.g. let n: u32 = 1;, or change the annotation.
E2002 unsupported-const
Error. A constant expression in a type (an array length, an Int bound or a const generic argument) uses something other than literals, arithmetic, constants and const parameters, or evaluating it forms a cycle.
const A: i64 = B;const B: i64 = A;fn f(n: Int<0, A>) {}Fix: build the constant only from literals, arithmetic and other acyclic constants, e.g. const A: i64 = 4;.
E2003 const-overflow
Error. Evaluating a constant expression in a type overflowed or divided by zero, or an integer literal in it is too large.
fn f(a: [u32; 10 / 0]) {}Fix: change the expression so its arithmetic stays in range, e.g. fn f(a: [u32; 10 / 2]) {}.
E2004 bad-int-bounds
Error. An Int<lo, hi> type is empty because lo > hi, or a bound does not fit in i64.
fn f(n: Int<5, 0>) {}Fix: write the bounds in ascending order: fn f(n: Int<0, 5>) {}.
E2005 wrong-generic-count
Error. A type or function receives a different number of generic arguments than it declares; Int needs exactly two bounds and primitives take none.
fn f(n: Int<5>) {}Fix: supply the declared number of arguments: fn f(n: Int<0, 5>) {}.
E2006 expected-type
Error. A path in type position resolves to something that is not a type, such as a function, enum variant, module or constant.
enum Route { A, B }fn f(r: Route::A) {}Fix: name the type instead: fn f(r: Route) {}.
E2007 expected-const
Error. A const generic parameter was given a type instead of a constant.
fn f(n: Int<u32, 5>) {}Fix: pass a constant value: fn f(n: Int<0, 5>) {}.
E2008 expected-trait
Error. A bound or impl … for names something that is not a trait.
struct Point { x: u32, y: u32 }fn same<T: Point>(a: T) {}Fix: use a trait in the bound, e.g. fn same<T: Eq>(a: T) {}.
E2009 expected-value
Error. A path in expression position resolves to something that is not a value, such as a module, a type parameter, or a struct or variant with named fields.
enum Shape { Circle { r: u32 }, Dot }fn f() { let s = Shape::Circle;}Fix: construct a value: let s = Shape::Circle { r: 1 };.
E2010 alias-cycle
Error. A type alias expands to itself, directly or through other aliases.
type A = B;type B = A;Fix: make one alias name a concrete type, e.g. type B = u32;.
E2011 infer-in-signature
Error. The placeholder _ appears in an item signature, where types must be written out.
fn f(n: _) -> u32 { 1 }Fix: write the type: fn f(n: u32) -> u32 { 1 }.
E2012 bad-literal
Error. An integer literal has a suffix that is not an integer type.
fn f() { let n = 5u7;}This snippet is illustrative: the parser already rejects an unknown suffix with E0001, so type inference reports E2012 only for a literal that reached it unchecked.
Fix: use a valid suffix or none: let n = 5u8;.
E2013 literal-out-of-range
Error. An integer literal, in an expression or a pattern, does not fit the integer type it is checked against.
fn literals() { let small: u8 = 300; let counter: Int<0, 5> = 6;}Fix: use a value within the type’s range or widen the type, e.g. let small: u16 = 300;.
E2014 int-mix
Error. An arithmetic operator combines two different integer types; there is no implicit conversion.
fn int_ranges(a: Int<0, 5>) { let mixed = a + 1u32;}Fix: convert one side explicitly with .into() or .saturate(), e.g. let mixed = a.into() + 1u32;.
E2015 bad-operands
Error. An operator is applied to operand types it does not support, such as ! on a non-bool/integer, negating an unsigned value, or bounded arithmetic whose result range overflows.
struct Point { x: u32, y: u32 }fn f(p: Point) -> bool { !p}Fix: apply the operator to a supported type, e.g. !flag on a bool.
E2016 divisor-may-be-zero
Error. The divisor of / or % has a bounded Int type whose range contains 0.
fn int_ranges(a: Int<0, 5>) { let quotient = a / a;}Fix: narrow the divisor’s type so it excludes zero first, e.g. take b: Int<1, 5> and write a / b.
E2017 not-eq
Error. == or != is used on a type that is never Eq, such as a closure.
fn equality() -> bool { let f = || 1u32; f == f}Fix: compare values that implement Eq, e.g. f() == f().
E2018 lossy-into
Error. .into() converts between integer types where the source does not always fit in the target.
fn conversions(wide: u32) { let byte: u8 = wide.into();}Fix: clamp explicitly: let byte: u8 = wide.saturate();.
E2019 as-cast
Error. Kagari has no as casts.
fn conversions(wide: u32) { let cast = wide as u8;}Fix: use .into() for lossless or .saturate() for clamping conversions: let cast: u8 = wide.saturate();.
E2020 unknown-field
Error. A struct initializer or field access names a field the type does not have.
struct Point { x: u32, y: u32 }fn fields(p: Point) -> u32 { let unknown = Point { x: 1, y: 2, z: 3 }; p.z}Fix: use only declared fields, e.g. p.x.
E2021 missing-field
Error. A struct initializer omits a field of the struct.
struct Point { x: u32, y: u32 }fn fields() { let missing = Point { x: 1 };}Fix: initialize every field: let p = Point { x: 1, y: 2 };.
E2022 unknown-method
Error. A method call names a method that neither the type nor any trait in scope provides.
struct Point { x: u32, y: u32 }fn methods(p: Point) { p.frobnicate();}Fix: call an existing method, or define frobnicate in an impl Point block.
E2023 not-a-method
Error. Method-call syntax is used on an associated function that has no self parameter.
struct Point { x: u32, y: u32 }impl Point { fn origin() -> Point { Point { x: 0, y: 0 } }}fn f(p: Point) { p.origin();}Fix: call it through the type: Point::origin().
E2024 wrong-arity
Error. A call supplies a different number of arguments than the function takes.
fn arity(x: u32) -> u32 { arity(x, x)}Fix: pass exactly the declared arguments: arity(x).
E2025 not-callable
Error. A call expression’s callee is not a function, function pointer or closure.
fn f(n: u32) -> u32 { n(1)}Fix: call a function value, or remove the parentheses if n was meant as a value.
E2026 unsatisfied-bound
Error. A generic argument does not implement a trait required by the callee’s bounds.
fn same<T: Eq>(a: T, b: T) -> bool { a == b}
fn bounds() -> bool { same(|| 1u32, || 2u32)}Fix: pass a type that implements the trait, e.g. same(1u32, 2u32).
E2027 bad-nav-start
Error. The first argument of nav::start does not name an #[entry] scene.
#[scene]pushdown fn Side() {}
fn navigation() { nav::start(Side, (), |_end| ());}Fix: start an #[entry] scene, e.g. mark Side with #[entry].
E2028 asset-path-not-literal
Error. The path passed to asset(…) or system_font(…) is not a string literal, so it cannot be checked at compile time.
const PATH: Text = "missing.png";const IMAGE: ImageAsset = asset(PATH);Fix: write the path inline: const IMAGE: ImageAsset = asset("missing.png");.
E2029 annotations-needed
Error. Inference could not determine a type, e.g. an empty collection never constrained afterwards, or a call/field/iteration on a value of unknown type.
fn annotations() { let list = Vec::new();}Fix: annotate the type: let list: Vec<u32> = Vec::new();.
E2030 open-range
Error. A range expression lacks a bound. As a value, a range needs both ends (a..b or
a..=b); a.., ..b, ..=b and .. are all reported. Open ranges exist only as
range patterns, which are a.., ..=b, a..b and
a..=b; there is no ..b pattern, and a bare .. in a pattern is the rest pattern, not a range.
The compiler’s message says that “a.., ..b and .. exist only in patterns”; read it as the
list above.
fn f() { for i in 0.. {}}Fix: give both bounds: for i in 0..10 {}.
E2031 not-iterable
Error. A for loop iterates over a value whose type cannot be iterated.
fn f(flag: bool) { for x in flag {}}Fix: iterate a range or collection, e.g. for x in 0..5 {}.
E2032 not-indexable
Error. Indexing […] is applied to a value whose type does not support it.
fn f(n: u32) -> u32 { n[0]}Fix: index an array, Vec or other indexable collection instead.
E2033 bad-deref
Error. The dereference operator * is applied to a value that is not a reference.
fn f(n: u32) -> u32 { *n}Fix: drop the *, or dereference an actual reference such as r: &u32.
E2034 bad-try
Error. The ? operator is used on a value that is not Option/Result, or in a function whose return type does not match the operand’s kind.
fn f(o: Option<u32>) -> u32 { o?}Fix: return the matching type, e.g. fn f(o: Option<u32>) -> Option<u32> { Some(o?) }.
E2035 bad-pattern
Error. A pattern’s shape does not fit what it names: a tuple pattern on a non-tuple variant, the wrong number of fields, an enum where a variant is expected, or a static in a pattern.
fn f(r: Option<u32>) -> u32 { match r { Some(a, b) => a, None => 0, }}Fix: match the declared shape: Some(a) => a,.
E2036 capturing-closure
Error. A closure that captures local variables is used where a function pointer is required.
fn f(n: u32) { let g: fn() -> u32 = || n;}Fix: pass the value as a parameter instead of capturing it, e.g. let g: fn(u32) -> u32 = |n| n;.
E2037 non-exhaustive-match
Error. A match does not cover every possible value of the scrutinee; the message lists uncovered patterns.
fn bounded(n: Int<0, 10>) -> u32 { match n { 0..=5 => 0, }}Fix: add arms for the missing values or a wildcard: 6..=10 => 1,.
E2038 refutable-pattern
Error. A pattern that can fail to match is used where matching must always succeed: let, function and closure parameters, or a for binding.
enum Route { A, B, C }fn refutable(r: Option<Route>) { let Some(x) = r;}Fix: use match or if let Some(x) = r { … } to handle the other cases.
W2039 unreachable-pattern
Warning. A match arm can never be reached because earlier arms already cover every value it matches.
enum Route { A, B, C }fn unreachable(r: Route) -> u32 { match r { Route::A | Route::B => 0, Route::B => 1, _ => 2, }}Fix: remove the unreachable arm or move it before the arms that cover it.
Last updated Oct 29, 2026