Skip to content

Diagnostic Reference

Every error, warning, and lint the Zolo toolchain emits. Click a code to see the full explanation, the typical cause, and the recommended fix.

with full explainers 180/214
Diagnostic Reference 214
01

Lint

24
float-equality
Comparing floats with `==` or `!=`

Floating-point equality is imprecise. Use `~=` (adaptive tolerance), `!~=`, or `math.approx_eq_abs/_rel(...)`. For exact comparisons use the `decimal` type.

unused-variable
Unused variable

A `let`-bound variable or parameter is never read. Prefix the name with `_` to silence the lint intentionally.

unused-function
Unused function

A top-level function is never called and is not marked `pub`, `@test`, `@bench`, `@export`, an HTTP route, or `main`.

unused-import
Unused import summary only

An imported name is never referenced in the file.

shadowed-variable
Variable shadows outer binding summary only

A `let` re-binds a name from an outer scope. Shadowing is sometimes intentional; rename one binding to silence the warning.

dead-code
Dead code after terminal statement summary only

Code after `return`, `break`, or `continue` is unreachable.

naming-convention
Naming convention violation

Functions/variables use `snake_case`; structs/enums/traits/effects use `PascalCase`.

non-exhaustive-match
Non-exhaustive match (legacy lint, no longer emitted)

Legacy alias: closed matches are now checked once by the type checker as `TE829`. Kept so older links keep a migration target.

must-use
`@must_use` value discarded summary only

A function or type annotated `@must_use` returned a value that the caller discarded. Bind it (`let _ = ...`) or consume it.

deprecated
Use of deprecated item summary only

A function annotated `@deprecated` was called. The annotation's message explains the replacement.

infinite-loop
Infinite loop with no exit summary only

A `loop`/`while true` block has no reachable `break`/`return`.

optional-typo
Likely typo on optional access summary only

A `Some(...)` / `None` / `?.` / `??` use that looks like a typo or misuse of the optional API.

unreachable-pattern
Unreachable `match` arm summary only

A pattern can never match because an earlier arm already covers it.

max-line-length
Line exceeds configured maximum length summary only

Configured via the project's lint config. Default is permissive; tighten in CI if you want hard limits.

max-nesting-depth
Block nested deeper than allowed summary only

Deep nesting hurts readability. Extract helpers or use early-return guard clauses.

max-parameters
Function has too many parameters summary only

Long parameter lists are a code-smell. Consider grouping related parameters into a struct.

max-function-length
Function body exceeds configured length summary only

Break the function into smaller helpers.

unknown-repr
Unknown `@repr(...)` policy summary only

Only `@repr(C)`, `@repr(packed)`, `@repr(transparent)`, and `@repr(zolo)` are recognized.

transparent-multi-field
`@repr(transparent)` on multi-field struct summary only

`transparent` only applies to single-field newtype-style structs.

layout-in-default-repr
`@layout(...)` on default-repr struct summary only

`@layout` only takes effect alongside an explicit `@repr`.

align-not-positive
`@layout(align = ...)` must be positive summary only

Alignment must be a positive power of two.

align-not-power-of-two
`@layout(align = ...)` must be a power of two summary only

Hardware alignment rules require power-of-two values (1, 2, 4, 8, ...).

align-too-large
`@layout(align = ...)` value too large summary only

The requested alignment exceeds the maximum the target platform supports.

size-not-positive
`@layout(size = ...)` must be positive summary only

Size cannot be zero or negative.

02

Parse

05
03

Type

168
E0001
Type mismatch (legacy) summary only

Equivalent to `TE001`. Emitted by the legacy message-pattern classifier when the new typeck did not attach a code.

E0002
Undefined variable (legacy) summary only

Legacy alias for `TE100`.

E0003
Undefined function / not callable (legacy) summary only

Legacy alias for `TE101`.

E0004
Cannot reassign (legacy) summary only

Legacy alias for `TE004`. The variable was declared with `let`; use `let mut` to allow reassignment.

E0005
Undefined field (legacy) summary only

Legacy alias for `TE102`.

E0006
Missing field summary only

A struct literal omits one or more required fields.

E0007
Wrong number of arguments (legacy) summary only

Legacy alias for `TE110`.

E0008
Return type mismatch summary only

The value being returned does not match the function's declared return type.

E0009
Duplicate declaration summary only

A name (function, variable, field, variant) was declared twice in the same scope.

E0010
Unknown type summary only

A type annotation refers to a type that the compiler cannot find.

TE001
type mismatch in `let` binding

The value assigned to a `let` binding does not satisfy the declared type annotation.

TE002
type mismatch in `const` binding

The value assigned to a `const` binding does not satisfy the declared type annotation.

TE003
const value is not a compile-time constant

`const` requires a constant-foldable expression. Use `let` for runtime values.

TE004
type mismatch in assignment

`let` bindings are immutable by default. Use `let mut x = ...` to allow reassignment, or use a fresh `let` shadow.

TE005
type mismatch in tuple-assignment slot

Operators like `+=`, `-=`, `*=` require both sides to be numeric (or strings for `+=`).

TE006
wrong return-value count for tuple return type

The function declared a tuple return but the actual `return` statement provides fewer values.

TE007
multiple return values without a tuple return type

The function returns more values than its declared single-value return type can hold.

TE008
array element type mismatch

An array literal mixes incompatible element types; arrays are homogeneous.

TE009
arithmetic on incompatible types

Binary arithmetic requires both operands to be numeric and (in strict mode) the same numeric type.

TE100
undefined variable

The name is not declared in any enclosing scope. The compiler attaches a "did you mean?" suggestion when a similar name exists.

TE101
call on a non-function type

The callee in a function-call expression is not a callable type.

TE102
struct has no such field

The struct does not declare this field. "Did you mean?" suggestions are attached for near-matches.

TE103
undefined type in enum variant

A type annotation or enum-variant field references a type the compiler cannot resolve.

TE104
no such method / unknown method

The receiver type does not have a method with this name. Check spelling, imports, and trait visibility.

TE105
stdlib module reference requires `use std::<name>`

A bare name matches a known standard-library module (`math`, `json`, `http`, `os`, …) that was never brought into scope. Unlike TE100, the compiler recognises the name and tells you exactly which `use` line is missing.

TE107
missing field in struct construction

A struct literal omits a field that has no default value and no zero-value fallback. Every non-defaultable field must be provided explicitly at construction time.

TE108
cannot derive `Default`: field has no `Default`

A struct decorated with `@derive(Default)` has a field whose type has no zero value and no explicit default, so no `Default` impl can be synthesised for it.

TE109
cannot infer field type from its default value

A struct field is written without a type annotation, relying on its default to infer the type (`name = value`) — but the default's type is ambiguous (e.g. `nil`, or an expression that resolves to `any`).

TE110
method argument-count mismatch

The number of arguments passed does not match the function's parameter count.

TE111
struct field default has the wrong type

An argument's type does not match the corresponding parameter's declared type.

TE112
`using`-embedded field is ambiguous between embeds

Two or more `using`-embedded fields declare a field with the same name, so a `.field` access on the outer struct can't tell which embed to promote it from.

TE113
`using` field must embed a struct type

A field marked `using` must embed another struct — its fields are what get promoted. A scalar, or any type that isn't a known struct declaration, has no fields to promote.

TE114
enum with numeric discriminants cannot be generic

An enum opted into numeric discriminants (a backing type, or an explicit `= n`) but is generic or has a payload-carrying variant. Discriminants only make sense for a flat, all-unit-variant enum.

TE115
discriminant does not fit the backing type

A variant's discriminant is outside the declared backing type's range (`enum E: u8` limits it to `0..=255`), so it could not round-trip through `to_int()`/`from_int()`.

TE116
duplicate discriminant value

Two variants of the same enum resolved to the same integer — either two explicit `= n` values collide, or an auto-incremented value landed on one already taken.

TE117
`@stable` enum requires an explicit discriminant

Under `@stable` auto-increment is disallowed: inserting a new variant in the middle would silently renumber every variant after it, breaking the encoding the annotation promises to keep.

TE118
discriminant must be an integer constant

A variant's `= expr` discriminant either didn't evaluate to an integer at compile time, or couldn't be evaluated as a compile-time constant at all.

TE119
`@flags` enum cannot be generic / must be unit variants

An `@flags` enum is generic or has a payload-carrying variant. `@flags` models a bitmask over a fixed, flat set of unit variants — there's no room for type parameters or payloads.

TE120
flag value must be a power of two or a composite of declared flags

Each `@flags` variant must be either a fresh single bit (auto-incremented or an explicit power of two) or a named composite built only from bits declared above it.

TE121
flag value does not fit the backing type

A flag's value is out of range for the enum's backing type — `enum: u8` bit-flags top out at `255` (bit 7).

TE122
two flags occupy the same bit

Two single-bit flags in the same `@flags` enum resolved to the same bit, usually because both were given the same explicit value.

TE123
struct has no such field in destructuring pattern

A destructuring pattern — `let Struct { … } = expr`, an anonymous `let { … }`, a parameter pattern, or a struct-destructuring assignment — names a field the struct doesn't have.

TE124
`let ... else` block must diverge

The `else` block can fall through. If it did, execution would continue into the pattern bindings using a value that did NOT match, so every path through `else` must return, panic, break or continue.

TE125
refutable pattern in `let` requires `else`

The pattern might not match (an enum-variant pattern, an array-length pattern, …) and has no `else` clause. Without one, a non-matching value would silently bind nonsense.

TE126
cannot infer the struct behind `let { ... }`

An anonymous struct pattern needs to know which struct it destructures, but the value's type doesn't resolve to a concrete struct — usually because it has no type annotation.

TE127
parameter pattern struct name does not match its annotation

A named struct pattern in parameter position (`fn f(StructName { … }: T)`) names a different struct than the parameter's own type annotation.

TE128
spread source must be a struct or record

A struct literal's trailing spread (`Struct { ..source }`) has a `source` that isn't a struct or record, so there are no fields to spread in.

TE129
tuple-assignment value-count mismatch

A tuple-destructuring assignment (`(a, b, c) = expr`) has a different number of targets than `expr` has values.

TE130
destructuring assignment only supports `=`

Compound operators (`+=`, `-=`, …) have no per-element meaning when the left-hand side is a whole pattern, and `..` spread makes no sense as an assignment target.

TE131
named-argument call requires a locally-declared function signature

A named argument (`f(name: value)`) does not match the callee's declared parameters — an unknown or duplicate name, a positional argument after a named one, a skipped middle parameter, or a callee with no locally-known signature.

TE132
`_` placeholder is only valid in pipe RHS / as `_.field`

The `_` placeholder is only valid as a direct argument in the RHS call of a `|>`/`?>` pipe stage (at most one per stage), or as the head of a field/method/index chain used as a call argument (`_.field`). A stray `_`, a second `_` in the same pipe stage, or `_` as a pipe's left-hand side are all rejected.

TE133
enum pattern references an unknown variant

A real, declared enum was identified for this site — as the base of `EnumName::variant`, or as the type of a scrutinee matched against a `.variant` shorthand pattern — but the variant name doesn't match any of its declared variants. A "did you mean?" suggestion is included in the message when a close match exists.

TE134
VM-prelude name has no native implementation

The name is part of the VM's always-in-scope prelude but the native/LLVM backend has no implementation for it. Building anyway would silently evaluate it to `nil` and exit 0, so the build fails instead.

TE135
unknown name has no native binding

A native/LLVM-only check: a bare identifier resolved to nothing at all. Without a Lua prelude to fall back on, it would silently lower to `nil` at runtime — the "typo turns into a quiet no-op" class this catches at build time.

TE136
cannot infer the enum for a `.Variant` shorthand in this position

The `.Variant` shorthand recovers its enum from the type the surrounding position expects, and this position supplies nothing usable — no expected type at all (an un-annotated `let`, an argument to a callee with no known signature), an un-pinned generic type parameter, or a type that is not an enum. Annotate the binding or write the qualified `Enum::Variant` form.

TE137
`.Variant` shorthand names an unknown variant of the inferred enum

The `.Variant` shorthand resolved its enum from the position's expected type, but that enum has no variant by that name. A "did you mean?" suggestion is included when a close match exists. The pattern form of the same mistake reports `TE133` instead.

TE138
reserved decl-module link prefix collision, or a decl-module body references a name this pass does not splice

A native/LLVM build could not splice a declaration module: either a user declaration starts with the compiler-reserved `__zolo_std_` prefix, or a reachable declaration-module function references a sibling item the linker cannot carry into the final program. Either case would let the AOT build silently diverge from the VM.

TE139
unclosed `<style>`/`<script>` raw text element

`<style>` and `<script>` are raw text elements: their content runs verbatim until the matching `</style>`/`</script>`, with no nested markup and no `{expr}` interpolation. Reaching the end of the file before that closing tag reports TE139 instead of the generic "unclosed element" message — usually a forgotten closing tag, or a `</tag`-shaped string inside the content (e.g. a JS string literal) that closed the block early.

TE140
Resource Graph recipe could not be sealed

A build-time Resource Graph recipe (`Resource.dir(...).seal()`) could not be sealed into its immutable Resource Image — a missing or non-directory path, an `include` pattern that matched nothing, a path escaping the resource root, a logical-path collision, or a file that could not be read while the snapshot was being sealed. There is no runtime fallback to the working directory: the build fails instead.

TE141
malformed Resource Graph value or Resource Image

The compiler received a malformed internal Resource Graph value, or a sealed Resource Image failed its integrity checks — an invalid recipe field (`root`, `includes`, `excludes`) or corrupted build state, distinct from `TE140`'s actionable input/sealing failures.

TE142
void conclusion used in value position

A `;` placed after a block's final expression suppresses its value, so the block concludes `void` instead of yielding a result. `TE142` fires when that terminator-caused void is used where a value is required — bound to a `let`, passed as an argument, and so on.

TE143
declared return type conflicts with a terminated tail

A function declares `-> T`, but a `;` after its final expression suppresses that value, so the body concludes `void` instead of a `T`. Unless another `return expr` supplies the value, the function can never satisfy its own signature.

TE144
write through a getter-only field accessor

The field declares `get` but no `set`, so assignments after construction are not allowed.

TE145
recursive access to the same field from its accessor

Accessing `self.<same-field>` inside its accessor would recurse; use the contextual backing name `field`.

TE146
field accessor visibility widens the stored field

An accessor may inherit or narrow its field visibility, but it cannot expose a private stored field publicly.

TE147
unwrapped fallible value conflicts with wrapper return

`?` propagates failure but unwraps success. A function returning `Result` or `Option` must wrap that success explicitly with `.Ok(...)` or `.Some(...)`.

TE148
Tailwind literal contains interpolation

A `tw"..."` literal must be a static list of Tailwind class names. Interpolating a value into it (`tw"bg-{color}-600"`) would hide part of the class name from the Tailwind build-time scanner, so Zolo rejects it — pick between complete literals using ordinary control flow instead.

TE150
`@inline` declaration has no Zolo body

Inline expansion requires a real Zolo body; native and plugin declarations must use a Zolo wrapper.

TE151
invalid or conflicting `@inline` policy

Use exactly one of `@inline`, `@inline(always)`, or `@inline(never)`.

TE152
recursive `@inline(always)` contract

An always-inline body cannot recursively expand itself; use a hint or split the recursive core.

TE153
`@inline(always)` contract cannot be expanded hygienically

The always-inline contract needs a supported hygienic body; simplify it or downgrade to bare `@inline`.

TE201
`@strict`: variable must have a type annotation

Strict typing requires every `let`/`const` to have an explicit type annotation.

TE202
`@strict`: parameter must have a type annotation

Strict typing requires every function parameter to have an explicit type.

TE210
syntax category is incompatible with the derive output slot

A structured derive returned syntax that cannot be inserted at its destination; derive results must currently be `Syntax<.Items>` or `Syntax<.Item>`.

TE211
quoted hole value cannot be converted to syntax

A `${value}` hole received a value with no safe source representation; insert a primitive or `Syntax<K>` node instead.

TE212
invalid identifier passed to `syntax.ident`

`syntax.ident(text)` received text that is not one valid, non-keyword Zolo identifier.

TE213
invalid or heterogeneous syntax spread

A `${..values}` spread received something other than a list or tuple of syntax nodes from one compatible category.

TE214
generated derive items violate the declared scope

The generated items escape the expansion scope declared by `@derive_for`, such as an unrelated free function from an impl-scoped derive.

TE216
deriver returned an unsupported value type

A `@derive_for` function returned a value other than the supported `str`, `Syntax<.Items>`, or `Syntax<.Item>` results.

TE217
typed derive attribute does not match its option schema

A namespaced derive attribute contains an unknown, duplicate, missing, non-literal, or incorrectly typed option.

TE218
derive target has no registered deriver

A type uses `@derive(T)`, but no deriver for `T` is available in scope. Zolo never skips this silently — a misspelled name must not produce a partially generated program that only fails at runtime. Import or declare the public function that exposes the deriver, conventionally exported under the same name as the capability.

TE220
await operand is not a Future or Task

`await` received a value whose known type is neither `Future<T>` nor `Task<T>`. Only those two wrappers can be suspended on; an ordinary value is already available and has nothing to await.

TE221
yield used outside a generator

`yield` is only valid inside a generator declared with `fn*`. An ordinary or `async fn` produces a single result and exposes no pull iterator to yield into.

TE222
generator returns a value

A generator (`fn*`) used `return value`. Termination and yielded items are separate concerns in a generator: `return` may stop it early, but its value is never produced as an iterator item — use `yield` for that.

TE223
generator yield type mismatch

A `yield`ed value does not satisfy the generator's declared element type. Every `yield` inside `fn* ... -> T` must produce a value assignable to `T`.

TE224
await is unsupported inside a generator

`await` appeared inside a `fn*` generator. Async generators have no scheduler contract shared by every backend yet, so Zolo rejects the combination instead of letting one backend resume it with different semantics than another.

TE225
unknown loop label

`break :label` or `continue :label` names no lexically active loop. Labels never cross a function/lambda boundary, and a `spawn`ed task or a callback scheduled with `every`, `after`, or `timeout` starts its own control-flow region, so it cannot jump to a loop in the caller.

TE226
duplicate active loop label

Two nested, simultaneously active loops declare the same label. A labelled exit would be ambiguous to a reader, even though the innermost declaration could be resolved mechanically.

TE227
break or continue used outside a loop

An unlabelled `break` or `continue` appears outside a loop. These statements can only transfer control within an enclosing `loop`, `while`, or `for`.

TE228
break value targets a statement loop

A `break` carrying a value targets `while` or `for`. Only the unconditional `loop` form is a value-producing expression, so a value-carrying `break` is only valid there.

TE229
loop break value type mismatch

The values carried by reachable `break`s disagree with the result type of a `loop` expression. A bare `break` contributes `void`, so it cannot exit a loop expected to produce a non-void value.

TE233
timeout result must be handled as Result

`timeout duration { ... }` returns `Result<Any, TimeoutError>`. The timeout failure is ordinary typed control flow — it is not an untyped record, and it is never silently converted to the successful value.

TE301
generic type argument count mismatch

The number of type arguments supplied does not match the generic's declared parameter count.

TE302
unknown trait

A trait bound, `impl` block, or `where` clause references a trait the compiler cannot find.

TE303
undeclared or overlapping trait impl member

An `impl Trait for Type` is not coherent with its trait declaration — either it adds a method the trait does not declare, or another implementation already satisfies the same parameterized target and trait instance.

TE304
trait method signature is incompatible

A method in `impl Trait for Type` does not match the trait after substituting `Self`, trait arguments, associated types, and method-generic parameters — parameter types/qualifiers, return type, generic bounds, and effect rows are all part of the contract.

TE305
associated type contract is incomplete or invalid

An implementation omits a required associated type, defines it more than once, names an associated type the trait does not declare, or supplies a type that fails the associated type's bounds.

TE480
associated type does not satisfy its declared bound

An implementation selected a concrete associated type that does not satisfy a bound the trait declared for it. The diagnostic names the implementation, the projected associated type, and the failed requirement — the original type is preserved, never silently widened to `Any`.

TE481
associated type is missing or cannot be resolved unambiguously

A trait declares an associated type with no default, but an implementation does not define it, so the compiler cannot project `Self::Item` (or another associated name) from that implementation.

TE482
trait type arguments are incompatible with the required witness

The concrete type implements the requested trait name, but with different type arguments. Trait witnesses are exact — implementing `Sink<str>` does not prove `Sink<int>`.

TE486
member is not common to every union alternative

A value typed as a union can be used without narrowing only through members shared by every alternative. Reading a field or calling a method that some alternatives lack would be valid for one runtime value and invalid for another.

TE708
island list without `key`

A warning, not a build failure. A `for` loop produces a list of rows and the row carrying an `@island` component has no `key` — the client-side morph then rewrites the row node-by-node on reorder instead of patching it in place, and the island loses its hydrated DOM state (signals reset, focus and scroll are lost).

TE719
handler in an `@island` cannot be compiled to JavaScript

An event handler inside an `@island` contains an expression the Verniz client lowering cannot represent as JavaScript. Server rendering could still produce the control, but publishing it without its handler would create an interactive-looking element that does nothing, so the build fails instead.

TE720
cannot assign to a derived cell (`let<signal>`)

An assignment targets a derived signal declared with `let<signal>`. A derived cell is defined by its initializer and recomputed from the source cells it reads — it is not writable state, so assigning to it would make it disagree with its own dependency graph.

TE721
`effect` in an `@island` cannot be compiled to JavaScript

An `effect` inside an `@island` contains behavior the Verniz client lowering cannot compile to JavaScript. Unlike server rendering, an island effect has no server-side half that can preserve the behavior — if it is not emitted to the client it never runs, so the build is rejected instead of silently dropping it.

TE727
`key` argument shadowed by the markup `key` attribute

A warning, not a build failure. A function declares its own `key` parameter, but `key` is a reserved markup attribute (spec V24) that is always routed through the extras map — it never reaches the function's own `key` parameter, which silently falls back to its default. The build succeeds and nothing else looks wrong.

TE730
`@()` interpolation outside a declaration value

`@(expr)` compiles to a CSS custom-property bridge (`var(--…)`), which only exists in declaration values — after the `:`, before the `;`. In a selector, a property name, or an at-rule prelude there is no `var()` to bridge to, and splicing user text there is a deliberate anti-feature. Move the dynamic part into a value, or toggle static classes in the markup.

TE731
runtime `children` on `<style>` requires `global`

A `<style children={expr}>` carries runtime content the compiler cannot see, so it can neither hoist nor scope it — scoping unknown text would be a lie. Spec §6.1: dynamic content must opt into `global` explicitly (`<style global children={…}>`), the one style form that stays a render node.

TE732
css interpolation value has a non-serializable type

A `@()` value travels as a CSS custom property, and only `str`, `int`, and `float` serialize into one. A value typed `bool`, `View`, map, struct, or function is rejected at compile time — at render it would stringify into garbage or vanish. Untyped (`Any`) values stay silent: this error never guesses.

TE733
`@()` glued to adjacent CSS value text

`@()` compiles to `var(--…)`, and CSS has no string concatenation in plain values — `var(--w)px` is a browser-dropped syntax error, not "number plus unit". Write `calc(@(x) * 1px)` or interpolate the full string (`@(f"{x}px")` — inside `@()` you are back in Zolo). `!important`, `/` and `*` in `calc()` are legal no-space neighbors.

TE734
malformed `:global()` — empty or nested

`:global(…)` exempts one compound from the hermetic scope stamp. An empty wrapper (`:global()`) exempts nothing, and a nested one (`:global(:global(a))`) escapes an escape — both can only be mistakes. In a `<style global>` body `:global()` is not Zolo syntax at all and passes through untouched.

TE735
scoped selector matches no element of the component (warning)

A warning, never a build failure. Hermetic scoping stamps every compound with the component class, so a selector naming a class/id/tag the component's own markup never produces is a dead rule — and `:root` under scope is structurally dead. Comes with a did-you-mean (edit distance ≤ 2) and the component's rendered set. Dynamic class/id values or `el`/`raw` calls open the set and suppress the warning — it never guesses.

TE736
`<style>` outside a component has no scope

A scoped `<style>` belongs to its surrounding component fn — the fn's class stamp is what the selectors scope to. In a top-level statement or an `impl`/`trait` method there is no component, so there is no scope. Add `global` (a static `<style global>` outside a component renders in place) or move it into a component fn. A body with `@()` reports this even under `global`: its values need a component root element.

TE737
`@()` with no root element to carry its value

Every `@()` value travels as a CSS custom property on the component's root element (the element literal in tail position), inheriting down the DOM. A component that delegates its whole view — no element root of its own — gives the values nowhere to ride. Make the tail an element literal (a wrapper `<div>` works) or drop the interpolation.

TE738
unknown CSS property (warning, curated table)

A warning, never a build failure. Property names are checked against a curated table shipped with the toolchain (static data, no registry download); a near miss comes back with a did-you-mean (edit distance ≤ 2). Names starting with `-` — vendor prefixes and `--custom` properties — are never checked, and neither are at-rule descriptors (`@font-face`'s `src`, …). A property newer than the table costs a squiggle, never a release.

TE740
HTML attribute is invalid for the element

A known HTML attribute is not valid for the authored element. Verniz validates native tags against its versioned DOM table; component props still go through the ordinary named-argument diagnostics.

TE741
DOM binding is invalid for the element

A two-way `bind:` binding is unsupported on the element, or its known source type is incompatible with the target DOM property — for example binding a `str` cell to `bind:checked`, which expects `bool`.

TE742
unknown DOM event

An event handler attribute names an event Verniz does not recognize on that element. Event names use their DOM attribute spelling, such as `onclick`, `oninput`, and `onchange`.

TE743
void HTML element has children or a closing tag

A void HTML element such as `input`, `img`, or `br` was written with children or an explicit closing tag. Void elements can never have content, so use the self-closing form instead.

TE744
control is missing a high-confidence accessible name

A high-confidence accessibility check: an `<img>` has no alternative text, or an interactive control has no name a screen reader can announce. It only fires when the missing name is certain — dynamic content, `children`, or an `HtmlAttrs` spread may still supply it at runtime.

TE745
invalid known ARIA attribute

A known ARIA attribute or role is used with an invalid spelling or value, or a label targets an element id that does not exist in the authored markup.

TE746
DOM ref target is not a compatible optional source cell

A `ref` target cannot receive a browser element. A `ref` must be an optional `DomRef` source cell (`var<signal> name: DomRef = nil`) declared inside the owning `@island`.

TE747
markup spread is not a compatible HtmlAttrs/static component record

A `{...spread}` is incompatible with its target. Dynamic forwarding onto a native element must be typed `HtmlAttrs`; a component spread must expose statically known record fields so ordinary prop checking stays active.

TE748
invalid or incompatible DOM event modifier

An event modifier (`prevent`, `stop`, `once`, `capture`, `passive`, `self`) is unknown, duplicated, or combined incompatibly — `passive` cannot be combined with `prevent`.

TE749
portal, boundary, or DOM ref cannot attach to its declared target

An attach contract cannot be fulfilled — the compiler catches statically empty portal targets, and the development attach verifier also reports missing portal targets, stale island markers, invalid binding properties, and refs that do not belong to the island.

TE750
action lifecycle member used on an ordinary function

A lifecycle member such as `pending`, `error`, or `state` was read from an ordinary function reference. Only a reference to a function declared `@action` has the nominal `ActionFn<...>` type and a client-side lane.

TE751
observable action lane has no owning island

Code outside any `@island` tries to observe an `ActionFn`'s lifecycle. An action reference stays callable on the server, but `pending`, `state`, `retry`, and the rest of its observable lifecycle are browser-owned capabilities that cannot cross an island or wire boundary.

TE752
unsafe or unknown mutation action policy

A mutation action requested an unknown policy, or a superseding/cancellation policy such as `.Latest`. A mutation already accepted by the server may still commit even after the client stops caring about its response, so cancelling only the client continuation would make the UI lie about the effect.

TE753
fallible action is called without observable error handling

An `ActionFn` returning `Result<_, E>` is called by an island that never observes the lane's failure state — reading `.error`/`.state`, or calling `.try_run(...)`. Without an explicit observer, a validation or transport failure is easy to miss.

TE754
explicit action lane has unstable list identity

A `.lane()` was created directly inside a rendered `for`. An explicit lane owns mutable client lifecycle state, but a list iteration has no stable lexical identity once rows are inserted, removed, or reordered.

TE763
value does not implement the browser Wire contract

A value crossing between Zolo and browser TypeScript has no deterministic JSON representation the Wire bridge accepts — the bridge never falls back to `any`. Functions, closures, handles, `ResourceFs`, non-string map keys, and unmarked user types stay on their origin side; structs/enums need `@wire`.

TE764
secret/private value is reachable from client code

A declaration marked `@secret` is reachable from a `@wire` type or an `@action` browser contract. Shipping it would place a private value in a generated declaration, codec, request, response, or browser bundle — removing `@secret` only to silence the diagnostic is unsafe.

TE775
content collection does not satisfy its schema or slug contract

Verniz could not turn an authored Markdown/JSON/TOML/YAML file into the metadata struct declared by `content.collection` — a missing or mistyped frontmatter field, an unparseable date, a non-portable path, or (for `ContentTransform`) a route callback/alias/fallback problem.

TE820
type does not implement a required trait (parameter bound)

A generic function is called with a type argument that doesn't implement a trait required by one of its bounds.

TE821
operator requires a generic parameter to carry a trait bound

An operator is used on a generic type parameter that carries no matching trait bound. Without it the compiler can't guarantee the operation is valid for every possible type argument.

TE822
trait does not exist

A bound in a function signature names a trait the compiler doesn't recognise.

TE823
operator requires a concrete type to implement a trait

An operator is used on a concrete struct/enum value whose type doesn't implement the required trait. Without it there's no method to drive the operator, so it would crash at runtime.

TE824
invalid qualified trait path

Qualified trait paths must be `core::<module>::<Trait>` or `std::<module>::<Trait>`, naming a `pub trait` actually declared there — in a generic bound and in an `impl` header alike.

TE825
incomplete trait impl: missing required method(s)

An `impl Trait for Type` is missing one or more required methods (those without a default body). Method and operator dispatch would otherwise fail at runtime.

TE826
collection method used directly on `Result`/`Option` (needs a guard)

A collection method (`each`, `filter`, `len`, …) was called on a `Result` or `Option` wrapper directly. Unwrap it first with `?>`, `?`, or `.unwrap()`.

TE827
`?.` used on a receiver that is never `Result`/`Option`

`?.` is null-safe chaining, not fallible unwrapping. A `Result` or `Option` is never `nil`, so the chain runs over the wrapper itself. Use `expr ?> .m(...)`, `let v = expr?`, or `expr!.m(...)` instead.

TE828
type is not iterable (`Iterator`/`IntoIterator` not implemented)

`for x in expr` needs `expr` to produce a sequence. Zolo iterates built-in collections and any type implementing `Iterator`/`IntoIterator`; a struct or enum implementing neither gives the loop nothing to produce.

TE829
non-exhaustive match on a closed type

`match` on a closed type — `bool`, an enum (including payloads), a closed-payload optional, a closed union, or tuples/records of closed fields — has unguarded arms that do not cover every possible value. A guarded arm never proves coverage, because its guard can evaluate to `false`.

TE830
enum pattern has the wrong payload shape

An enum pattern names a real variant but destructures it with the wrong payload shape — unit, tuple, and struct variants each require their own pattern form, and tuple arity or struct fields must agree with the declaration.

TE831
or-pattern alternatives bind incompatible names or types

Every alternative of an or-pattern (`A(x) | B(x)`) must introduce the same names with compatible types, since the match body runs after any alternative succeeds and can read whichever name it bound.

TE832
postfix `?`/`?>` requires a statically fallible operand

Postfix `?` and the fallible pipe `?>` require a value that can fail — `T?`, `Option<T>`, or `Result<T, E>`. Applying either to a statically plain value has no failure path to propagate.

TE833
fallible failure path is incompatible with the enclosing return type

Postfix `?`/`?>` returns the matching `nil`, `Option.None`, or `Result.Err` from the enclosing function, and that failure must be compatible with its declared return type. `Option.None` is not interchangeable with `Result.Err`, and a nilable failure is never silently boxed into either enum.

TE834
nil-only operator used directly on boxed `Option`/`Result`

`?.` and `??` are nil-only operators, but `Option<T>` and `Result<T, E>` are boxed enum values — neither wrapper is itself `nil`, so `??` cannot unwrap it. Use postfix `?`, pattern matching, or an explicit wrapper method such as `unwrap_or` instead.

TE835
invalid cast; use parsing, a predicate, or a domain conversion

`as` performs only compiler-known casts — it does not parse text, compute truthiness, serialize data, or run a conversion implemented by a user type. Use `parse::<T>()`, `to_string()`, `try_into::<T>()`, or an explicit comparison instead.

TE836
checked cast can never succeed or has no exact implementation

`value as? T` promises an exact, runtime-checked conversion, but the source and destination types have no value-preserving checked path — for example parsing text is not casting. Use `parse`, `try_into`, or a numeric cast policy instead.

TE837
numeric cast may lose information

A numeric `as` may narrow a range, change signedness, discard a fractional part, or round an integer too large for the destination float. Use `as?` when only an exact value is acceptable, or `cast` with a named rounding/overflow policy when loss is intentional.

TE838
unchecked cast from a dynamic value

A bare `as` cast from `Any` cannot prove the runtime value actually has the requested type, so Zolo rejects it. Use a checked cast (`as?`) or flow narrowing (`is`) instead.

TE839
stringification through `as str` is legacy behavior

`value as str` mixes casting with formatting, and remains available only as a migration bridge. Use `.to_string()` explicitly, or a codec such as `json.encode` when producing a wire format.

TE840
redundant cast

The source value already has the requested type, so `as Type` communicates no new intent and performs no work. Remove the redundant cast expression.

TE841
numeric cast policy is incompatible with the source or target

A numeric `cast` policy applies only to the conversion family it names — `.wrap` is defined only for integer-to-integer conversion, while `.trunc`/`.floor`/`.ceil`/`.nearest_even` convert floating-point values. Choose a compatible policy, or use `as?` when only exact values are accepted.

TE842
no direct From/TryFrom conversion implementation

`into::<T>()` requires a direct `impl From<Source> for T`, and `try_into::<T>()` requires a direct `impl TryFrom<Source> for T`. Zolo never invents a conversion chain through an intermediate type — implement the matching trait, or call the intended constructor explicitly.

TE843
parse source or destination type is unsupported

Generic `parse::<T>()` is a text operation: its receiver must be `str` or `bytes`, and `T` must be one of the numeric types supported by the core parser. Use a domain-specific decoder (such as `json.decode`) for structured data instead.

TE844
unsafe bitcast requires equal-size numeric layouts

`unsafe bitcast::<T>(value)` reinterprets representation bits rather than performing a numeric or domain conversion, so both types must be fixed-width numeric types with exactly the same bit width. Use `as?`, `cast::<T>(policy)`, `into`, or `try_into` to actually change the value instead.

TE845
From/TryFrom implementation violates conversion coherence

An `impl From<S>`/`TryFrom<S>` is only legal in the package that owns the source `S` or the destination type — otherwise two unrelated packages could define competing meanings for the same conversion. Zolo also rejects overlapping implementations and never searches conversion chains such as `A -> B -> C`.

TE846
checked cast or `is` target has no runtime witness

`as?` and `is` can only probe a primitive category or the declared name of a user type (generic types by their base name). A structural shape such as `[int]`, `{str: int}`, a record, a tuple, a union or `T?` has no runtime witness: probe the category (`as? array`, `is map`) or decode the value with `@derive(Deserialize)` to validate its elements.

TE970
tagged template has no matching tag function in scope

A tagged template `tag"…"` is not special syntax — it lowers to an ordinary call to a function named `tag`, and no such function is in scope.

TE976
non-expression statement inside `parallel { }`

`parallel { … }` runs each top-level statement as its own concurrent task, so every statement in the block must be an expression that can become one.

TM100
`super` used outside a mixin body

Compiler diagnostic TM100: `super` used outside a mixin body.

TM112
self-using mixin applied to a free function

Compiler diagnostic TM112: self-using mixin applied to a free function.

TM113
mixin application argument contract failure

Compiler diagnostic TM113: mixin application argument contract failure.

TM114
mixin result is incompatible with the decorated target

Compiler diagnostic TM114: mixin result is incompatible with the decorated target.

TM115
explicit `super(...)` arguments do not match the target

Compiler diagnostic TM115: explicit `super(...)` arguments do not match the target.

TM116
runtime mixin applied to a non-callable declaration

Compiler diagnostic TM116: runtime mixin applied to a non-callable declaration.

04

Effects

16
TE800
function performs an effect but does not declare `with`

A function performs an effect (`!io`, `!net`, `!fs`, ...) it did not declare in its signature.

TE801
unknown effect in `with` clause

An effect was performed but no enclosing `handle` block handles it.

TE802
calls a function requiring an undeclared effect

A `handle` block tries to handle an operation the effect did not declare.

TE803
`handle` block does not cover all operations of the effect

A `handle` block is missing the implementation for one of the effect's declared operations.

TE804
effect has no such operation

The handler references an operation name that does not exist on the effect.

TE805
handler arm parameter-count mismatch

A function signature or handler references an effect the compiler cannot find.

TE806
duplicate handler arm

A `perform` call or handler operation does not match the effect's declared signature.

TE807
handler value coverage is incomplete

`handle … with <handler_value>` uses a handler value that covers only some of an effect's operations. The error fires at the `with` site and names the missing operation(s).

TE808
`perform` argument type mismatch

A `perform Effect::op(…)` call passed an argument whose type doesn't match the operation's declared parameter type.

TE809
function performs effects but does not declare any of them

The summary form of TE800: instead of reporting each `perform` site, it collects every effect a boundary function actually needs and reports them all at the signature.

TE810
handler covers an operation the body never performs (warning)

A warning, not a build failure. A `handle` block using an explicitly annotated `handler<…>` value covers an effect the handled body never actually performs.

TE811
generic parameter bound as both a type and a row variable

A generic parameter is used both as a type parameter and as a row-variable tail in a `with` clause (`{Fs | e}`). A single name can't mean both a type and a set of extra effects.

TE812
multi-shot effect is not supported on the native backend

A `perform` targets an effect operation declared `multi` (resumable more than once). Multi-shot continuations are a VM-only capability today.

TE813
cannot infer a type argument for an effect operation

A generic effect's type parameter couldn't be resolved at a `perform` site — neither the argument types nor a `with Effect<Concrete>` pin gave it a concrete type.

TE814
`handle ... with h` requires `h: handler<...>`

`h` must be something whose type is `handler<…>`. If it resolves to anything else, there's no arm set to dispatch the performed operations to.

TE815
function requiring an effect passed where a pure function is expected

A parameter typed as a plain function (`fn(...) -> T`, no `with` clause) promises purity — nothing it runs performs an effect the caller doesn't already know about. Passing a function that itself requires an effect there lets that effect escape completely undeclared, the same class of leak `TE802` blocks in the ordinary call direction.

05

Runtime

01

Global index

Find your way through Zolo

Try an idea

Start here

9 results

9 results

enespt-br