Reference

Error codes

Every diagnostic Undra raises, from a macro at compile time, from schema validation, from the runtime or from the undra command, has a stable code, a fixed shape and a fix. The link at the end of each message lands on its code below.

How to read one

A diagnostic says what is wrong, why the rule exists and how to fix it. This one is verbatim from the macro test suite:

text
error[undra::E0004]: callback `Arc<dyn Listener>` cannot be a field of a record or enum (`Listener` is a callback interface)
  = note: a callback is an instance with a lifetime, not a value: it cannot be copied, compared, stored in a record or mirrored from a signal
  = help: keep an id or a record here, and take the callback as a parameter of the method that needs it
  = docs: https://shreypdev.github.io/undra/docs/errors.html#E0004

All codes

CodeMeaning
C0001no undra.toml from start up to the filesystem root
C0002a configuration or schema file is unusable
C0003a tool is not installed
C0004a build tool exited with a failure
C0005the core crate is missing, or is not an Undra core
C0006the schema could not be extracted from the built core
C0007the schema cannot be turned into bindings (bindgen diagnostics)
C0008the command would overwrite something it must not
C0009an argument is unusable
C0010an I/O operation failed
C0011the Rust toolchain lacks a compilation target
C0012the platform is not available on this machine
C0013the dev server failed to start or crashed
C0014the project's Undra does not match: the core's comes from elsewhere, or it is newer
E0001unsupported type in a public position
E0002generic parameter, or a generic type spelled with its arguments
E0003lifetime in a public signature
E0004a trait object, dyn or impl Trait that is not a callback parameter, or a callback where one may not stand (ADR-041)
E0005Result / Stream outside return position
E0006map key type not allowed
E0007unsupported item shape or placement of an Undra attribute
E0008unknown or misplaced #[undra(..)] attribute or macro argument
E0010invalid #[undra::error] variant
E0011store and #[undra::api(store)] impl block disagree
E0012trait object in a record field
E0013store cannot be restored automatically
E0020&mut self receiver
E0021self by value
E0022non-Send future in an async method: rustc's own error, pointed at the method by an assertion named after this code
E0030port method with a non-wire parameter
E0031event port method that is not a plain fn(..) returning ()
E0032invalid port trait shape
E0033the error type of a port method has no From<PortError>
E0040query without key, mutation with stale, or another invalid query argument
E0041query or mutation function with an invalid signature
E0042query whose success value is () or an Option
E0050duplicate type name, id or variant index
E0051a name that collides after case conversion or is not an identifier
E0052an item named like a standard library item, with another id
E0060a spelling that looks like a built-in Undra type is another type
E0061the name written is not the declared name of the type, or the type is not declared with #[undra::api]
E0062a port call could not be answered and its method has no error channel: a runtime message
E0063nested Option<Option<T>>
E0064an object (#[undra::api] impl) used where a value is expected, or a value used as an object, or an object where objects may not stand (ADR-040)
E0065a signal of a store written off its owning runtime's core (ADR-035): a runtime message
E0066a #[undra::migrate] hook with a wrong target or shape (ADR-037; addition)
E0070a named instantiation of a generic data type that is declared twice or outside the crate of its template
E0071a method of a #[undra::callback] trait that is neither fire-and-forget nor async with a Result, or whose name starts with __ (ADR-041)
E0072the instantiation list of a generic function or method (generic(T = [Todo, Note])) is empty, repeats a type, lists something that is not a named value type, names a type parameter the function does not have, or the function has several type parameters; a schema whose generic labels do not describe their definitions (ADR-058; addition)
E0073an infinite query that does not meet ADR-043's shape: no item_key or one that names no field of the rows, no or more than one #[undra(cursor)] parameter, a cursor that is not Option<C> or is in the key, a success type that is not Page<T, C>, rows that are not a record
E0074the impl block of a generic object that is not for the type with its own type parameters, each exactly once, or a method of a generic object with type parameters of its own (ADR-058; addition)

Types and shapes#

E0001 unsupported type in a public position#

Raised by macros, schema validation, the Encode/Decode bounds.

unsupported type in a public position (lists the type and the allowed set); includes i128/u128 (the help points at Decimal, Uuid or a String newtype), DateTime<Local> and DateTime<FixedOffset> ("convert to Utc; offsets do not cross"), a type of the uuid, chrono, time, rust_decimal or bytes crate that only that crate has (DateTime<Utc>, OffsetDateTime, TimeDelta, ..) spelled without the matching feature of undra (one error naming the feature), a Lazy<T> that is not a store field, or is inside a Signal, Computed or DerivedList (ADR-043), a DerivedList field without its row type (ADR-039), Handle (no schema type; an object crosses as Arc<T> or &T, ADR-040), Arc<T> of a built-in or an Rc, a Result whose error type is not a #[undra::error] enum, a Ctx parameter that is misplaced (on a method, not first, or &mut), and a type used as a value that cannot cross (an Encode/Decode bound that is not met: a struct without #[undra::api])

What you seeWhyFix
Plain cannot cross the boundary by valuea value crosses as a scalar, String, Bytes, Vec, Option, a map, Duration, Timestamp, Uuid, Decimal, or a type declared with #[undra::api] (records, enums) or #[undra::error]; an object (#[undra::api] impl) crosses by handle, never as a valuedeclare Plain with #[undra::api], or return a record with the data the platform needs; a type of the uuid, chrono, time, rust_decimal or bytes crate crosses once you enable that feature of undra
() cannot be used as a field() occupies zero bytes on the wire, so it is only legal as a return type or as a variant without fields; Vec<()>, Option<()> and maps of () defeat length validationremove the value, or use bool if you need a marker
DateTime<Local> cannot cross the boundarya Timestamp is an instant in milliseconds since the Unix epoch, in UTC; a date-time with a local time zone or a fixed offset has no one value every platform reads alike, and the offset itself would be lostconvert to Utc (value.with_timezone(&Utc)) and spell DateTime<Utc>; offsets do not cross
DateTime<FixedOffset> cannot cross the boundarya Timestamp is an instant in milliseconds since the Unix epoch, in UTC; a date-time with a local time zone or a fixed offset has no one value every platform reads alike, and the offset itself would be lostconvert to Utc (value.with_timezone(&Utc)) and spell DateTime<Utc>; offsets do not cross
DerivedList needs the type of its rowsa derived list is a Vec of rows the platforms mirror, so the schema needs the row type, written as the one type argumentwrite DerivedList<Row> for visible, with the type the pipeline's build() produces
&str cannot cross the boundaryreferences have no wire representation; every value crosses by copyuse an owned String

E0002 generic parameter, or a generic type spelled with its arguments#

Raised by macros.

generic parameter on a #[undra::api] item that is not a template, on an error enum, object, store, function, method, constructor, port, callback, query or mutation (the text of each says what to write instead: #[undra::api(generic)] and a named instantiation for a data type; generic(T = [Todo, Note]), the list of types, for a function or method, ADR-058); a const parameter, a where clause or a default type parameter ("only type parameters are supported"); a generic type spelled with its arguments (Page<Todo>: declare #[undra::api] pub type TodoPage = Page<Todo>; and write TodoPage); the wrong number of type arguments for a template (ADR-042)

What you seeWhyFix
Page<Note> has no name (in first_page<Note>)the schema names every type, and an instantiated generic type is named by the alias that declares it; Page<Note> is reached here by putting a listed type in place of a type parameter, and no alias declares itdeclare #[undra::api] pub type NotePage = Page<Note>; next to Page
generic parameter T on newest has no list of typesthe schema describes concrete functions and the platforms call them by id: a generic function crosses once for each type it is declared for, and its callers are on the platforms, where the core cannot see themlist the types the platforms may use: #[undra::api(generic(T = [Todo, Note]))]; each becomes a function of its own, newest<Todo> and newest<Note>
generic parameter T on pinned has no list of typesthe schema describes concrete functions and the platforms call them by id: a generic function crosses once for each type it is declared for, and its callers are on the platforms, where the core cannot see themlist the types the platforms may use: #[undra(generic(T = [Todo, Note]))] on the method; each becomes a method of its own, pinned<Todo> and pinned<Note>
generic parameter T on the constructor createa constructor returns the object, and the object has no such parameter: the platforms could not say which create they meantake a concrete type or an enum of the cases; make the object generic if the parameter belongs to it
generic parameter T on the store Selectionthe schema describes concrete objects: a generic object crosses once per instantiation, each under a name of its own, which the platforms generate a class forwrite #[undra::store(generic)], mark its impl block #[undra::api(store, generic)] and declare each instantiation: #[undra::api] pub type TodoSelection = Selection<Todo>;
generic parameter T on the impl block of Cachethe schema describes concrete objects: a generic object crosses once per instantiation, each under a name of its own, which the platforms generate a class formark the block #[undra::api(generic)] (#[undra::api(store, generic)] for a store) and declare each instantiation: #[undra::api] pub type TodoSelection = Selection<Todo>;

E0003 lifetime in a public signature#

Raised by macros.

lifetime in a public signature

What you seeWhyFix
lifetime 'static in &'static streverything crosses the boundary by value; a borrow cannot outlive the call that made ituse an owned type such as String or Vec<T>
lifetime 'a on WithLifetimeeverything crosses the boundary by value; a borrow cannot outlive the call that made itremove the lifetime parameter and use owned types
lifetime 'a in &'a streverything crosses the boundary by value; a borrow cannot outlive the call that made ituse an owned type such as String or Vec<T>
lifetime 'a on Labeleverything crosses the boundary by value; a borrow cannot outlive the call that made itremove the lifetime parameter and use owned types

E0004 a trait object, dyn or impl Trait that is not a callback parameter, or a callback where one may not stand (ADR-041)#

Raised by macros, schema validation (a bound the compiler checks).

trait object / dyn / Box<dyn Fn> / closure / function pointer / an impl Trait that is not a stream (declare a #[undra::callback] trait and take Arc<dyn Trait>, ADR-041); a callback (Arc<dyn Trait>) where one may not stand (anywhere but a parameter of a method, constructor or function, alone or in an Option: a return, a field, a signal, a port or query value), with the help of its position; Arc<dyn Trait> of a trait that is not a #[undra::callback] (the CallbackInterface bound, a branded message)

What you seeWhyFix
callback Arc<dyn Listener> cannot be a field of a record or enum (Listener is a callback interface)a callback is an instance with a lifetime, not a value: it cannot be copied, compared, stored in a record or mirrored from a signalkeep an id or a record here, and take the callback as a parameter of the method that needs it
callback Arc<dyn Listener> cannot be used here (Listener is a callback interface)a callback is an object the host implements and passes in for the core to call; the core never hands one outreturn a plain value, or an object (Arc<T>) the host can call methods on
callback Arc<dyn Listener> cannot be used here (Listener is a callback interface)a callback may be a parameter of a method, constructor or function, alone or in an Option; it cannot be nested in another typetake one Arc<dyn Trait> (or Option<Arc<dyn Trait>>) per parameter
closure type Arc<dyn Fn(u32) + Send + Sync> cannot cross the boundarycallbacks have no wire representationdeclare a #[undra::callback] trait and take Arc<dyn Trait>
dyn Platform cannot be taken as a callbackonly a trait declared with #[undra::callback] has a proxy the core can call and a generated protocol the host implementsadd #[undra::callback] to the trait, or pass a record or an id
dyn Plain cannot be taken as a callbackonly a trait declared with #[undra::callback] has a proxy the core can call and a generated protocol the host implementsadd #[undra::callback] to the trait, or pass a record or an id

E0005 Result / Stream outside return position#

Raised by macros, schema validation.

Result or Stream outside return position; a Result<impl Stream<Item = Result<T, E1>>, E2> whose two error types differ (ADR-036)

What you seeWhyFix
Result<u32, String> cannot be used as a fieldResult<T, E> is how a method reports a typed error; it is only legal as the outermost type of a returnreturn the Result from the method and keep only plain values in fields, parameters and nested types
Result<u32, String> cannot be used as a parameterResult<T, E> is how a method reports a typed error; it is only legal as the outermost type of a returnreturn the Result from the method and keep only plain values in fields, parameters and nested types
the items of the stream in Result<impl Stream<Item = Result<u32, ItemError>>, OpenError> fail with ItemError but its opening fails with OpenErrora stream method has one error type: the platforms throw it whether the stream fails to open or ends with an error part-wayuse the same #[undra::error] enum for both (OpenError), or one enum with a variant for each case
Result<u32, String> cannot be nested inside another typeResult<T, E> is how a method reports a typed error; it is only legal as the outermost type of a returnreturn the Result from the method and keep only plain values in fields, parameters and nested types
result<u8,named:Oops> at record Todo, field outcome: Result is only allowed as the outermost type of a returnResult<T, E> is how a method reports a typed error, so it has no meaning inside a field, a parameter or another typereturn the Result from the method and keep plain values in fields, parameters and nested types

E0006 map key type not allowed#

Raised by macros, schema validation, a bound the compiler checks.

map key type not allowed: String, integers, bool, Uuid and newtypes of those are keys; a float, a Decimal, a record, a collection, and a newtype of one of those are not (the macros assert K: MapKey at every HashMap/BTreeMap key position, ADR-042)

What you seeWhyFix
f64 cannot be a map keymap keys must be String, an integer, bool, Uuid or a newtype of one of those: they compare and hash identically on every platform (floats, decimals, records and collections do not)use one of those key types, a newtype of one (struct UserId(pub Uuid);), or a Vec of records with an explicit key field
Decimal cannot be a map keymap keys must be String, an integer, bool, Uuid or a newtype of one of those: they compare and hash identically on every platform (floats, decimals, records and collections do not)use one of those key types, a newtype of one (struct UserId(pub Uuid);), or a Vec of records with an explicit key field
undra::prelude::Decimal cannot be a map keymap keys must be String, an integer, bool, Uuid or a newtype of one of those: they compare and hash identically on every platform (floats, decimals, records and collections do not)use one of those key types, a newtype of one (struct UserId(pub Uuid);), or a Vec of records with an explicit key field
Loose cannot be a map keymap keys must be String, an integer, bool, Uuid or a newtype of one of those: they compare and hash identically on every platform (floats, decimals, records and collections do not)use one of those key types, a newtype of one (struct UserId(pub Uuid);), or a Vec of records with an explicit key field
f32 at record Scores, field by_weight is not a valid map keymap keys must compare and hash the same on every platform: String, an integer type, bool, Uuid and a newtype of one of those do, floats, decimals and composite keys do notuse one of those key types, or a Vec of records with an explicit key field
decimal at record Prices, field by_amount is not a valid map keymap keys must compare and hash the same on every platform: String, an integer type, bool, Uuid and a newtype of one of those do, floats, decimals and composite keys do notuse one of those key types, or a Vec of records with an explicit key field

E0007 unsupported item shape or placement of an Undra attribute#

Raised by macros.

unsupported item shape (a unit struct, a tuple struct of two or more fields or none (one field is a newtype), a record without fields, a type alias that does not name an instantiation of a #[undra::api(generic)] type, an empty enum, an impl item that is neither a method nor a constructor, a receiver that is not &self, a store that is not a struct with named fields, the reserved field name __undra_cell, #[undra::port] on an inherent impl, an Undra attribute on the wrong kind of item, #[undra::api] on a method, #[undra::query] or #[undra::mutation] inside an impl block or a port trait, a function whose signature uses Self, a second #[undra::api] impl block for one type). A second impl block is reported by rustc as "the name _undra_error_E0007_<Type>_has_two_undra_api_impl_blocks_merge_them_into_one is defined multiple times": merge the blocks. A query or mutation inside an impl block that is not #[undra::api] cannot be seen by its macro; rustc then reports "macro definition is not supported in traits or impls" and "cannot find macro _undra_error_E0007_a_query_is_a_free_function_move_it_out_of_the_impl_block", which is this code: move the function out of the block

What you seeWhyFix
#[undra::api] on new, which is an associated function: its signature uses SelfSelf only exists inside an impl block, and #[undra::api] on a function exposes a free function; the functions of an object are exposed by putting the attribute on the impl block they are inremove #[undra::api] from new and write #[undra::api] above the impl block (it exposes every pub fn in it)
#[undra::query] on the method forecast of a port traita port is a list of methods the platform implements; the attribute applies to a whole item (a type or a free function), never to a trait methodremove the attribute from forecast; a #[undra::query] is a free async fn(ctx: &Ctx, ..) that calls the port as weather(ctx).forecast(..), so write it outside the trait
#[undra::api] on the method now of a port traita port is a list of methods the platform implements; the attribute applies to a whole item (a type or a free function), never to a trait methodremove the attribute from now; a function the core exposes that calls the port is a free #[undra::api] fn(ctx: &Ctx, ..) outside the trait, calling weather(ctx).now(..)
#[undra::query] on admins, which is inside an impl block: its signature uses Selfa query is a free function, and the macro generates a struct next to it, which an impl block cannot holdmove admins out of the impl block, to module level, and spell out the type instead of Self
#[undra::store] cannot be applied to an enum#[undra::store] applies to a structmove #[undra::store] onto a struct, or remove it
#[undra::api] on the type alias Alias, which does not name an instantiationa type alias is not a schema type of its own; the only alias that is names an instantiation of a generic data type declared with #[undra::api(generic)], so it can be given a name the platforms generate a type forwrite #[undra::api] pub type Alias = Page<Todo>; for a template Page, or remove #[undra::api] and write the aliased type where it is used

E0008 unknown or misplaced #[undra(..)] attribute or macro argument#

Raised by macros.

unknown or misplaced #[undra(..)] attribute or macro argument (an unknown key, with the nearest name suggested, a value of the wrong kind or a value on a flag, key on a signal that is not a Signal<Vec<T>> or a DerivedList<T> (a keyed Computed is pointed at DerivedList<T>), a DerivedList<T> without key (ADR-039), key naming no field of the list's items (for a generic store: of the row type of one instantiation, at its alias), generic on a type, an impl block or a store that has no type parameter, generic(..) with a list on a struct, an enum or an impl block (a list instantiates a function; a type is instantiated by an alias, ADR-058), generic alone on a function, a malformed list, #[cfg] on a public item, an invalid crate = ".." path); a cfg_attr whose attributes are all documentation or lint levels is accepted

What you seeWhyFix
#[undra(key = "idd")] on typo names no field of Rowkey names the field of the list's items that identifies them, and Row has the fields id, titlewrite the name of one of those fields as the key
#[undra(key = "n")] on not_a_record names no field of u32key names the field of the list's items that identifies them, and u32 has no fields (only a record declared with #[undra::api] has any)write the name of one of those fields as the key
#[undra(key = "not a name")] on not_a_name names no field of Taggedkey names the field of the list's items that identifies them, and Tagged has the fields type, idwrite the name of one of those fields as the key
unknown option defualt in #[undra(..)]the options are crate = "path" (items), default (record fields), key = "field" and no_coalesce (store signal fields), coalesce (fire-and-forget methods of a callback interface) and generic(T = [..]) (methods with a type parameter)did you mean default? Otherwise remove defualt
unknown option frobnicate in #[undra(..)]the options are crate = "path" (items), default (record fields), key = "field" and no_coalesce (store signal fields), coalesce (fire-and-forget methods of a callback interface) and generic(T = [..]) (methods with a type parameter)remove frobnicate, or use one of: crate, default, key, no_coalesce, coalesce, generic
#[undra(key)] is not valid on a record or variant fieldkey = "field" turns a store's Signal<Vec<T>> into a keyed list that ships patchesmove it to a Signal<Vec<T>> field of a #[undra::store] struct, or remove it

Errors and stores#

E0010 invalid #[undra::error] variant#

Raised by macros, schema validation.

#[undra::error] variant without #[error(..)], a message with an implicit {} (write {0} or {name}), #[error], #[from] or #[source] on a plain #[undra::api] enum

What you seeWhyFix
variant NotFound has no #[error(..)] messageevery variant of a #[undra::error] enum needs a message, because the platforms show it to users and logsadd #[error("what went wrong")], or #[error(transparent)] to forward to the inner error
invalid message for variant Missing: {1} refers to field 1, but the variant has 1the message is a template over the variant's fieldsuse {0}, {1}, .. for tuple fields and {name} for named fields
#[error(transparent)] on variant Both needs exactly one field, found 2transparent forwards Display and source() to the variant's only fieldgive the variant a single field holding the inner error
#[error] on the variant A belongs to #[undra::error], not #[undra::api]#[error(..)], #[from] and #[source] are the helper attributes of error enums; a plain #[undra::api] enum has no messages, Display or From implschange the enum's attribute to #[undra::error], or remove the helper attribute
#[from] on the field 0 belongs to #[undra::error], not #[undra::api]#[error(..)], #[from] and #[source] are the helper attributes of error enums; a plain #[undra::api] enum has no messages, Display or From implschange the enum's attribute to #[undra::error], or remove the helper attribute
variant Unmessaged has no #[error(..)] messageevery variant of a #[undra::error] enum needs a message, because the platforms show it to users and logsadd #[error("what went wrong")], or #[error(transparent)] to forward to the inner error

E0011 store and #[undra::api(store)] impl block disagree#

Raised by macros, schema validation.

#[undra::store] and its #[undra::api(store)] impl block disagree, including a store with no impl block and a #[undra::api(store)] block without a constructor (a type takes one block; a constructor in another block is not seen); a store without a constructor in the schema; for a generic store (ADR-058) the impl block below its struct in the same module: a block that is not below a #[undra::store(generic)] struct is reported by rustc as "cannot find macro _undra_error_E0011_<Type>_is_not_a_generic_store_declared_above_this_impl_block_in_the_same_module", a #[undra::store(generic)] whose block is #[undra::api(generic)] without store by a const assertion at the alias, and a #[undra::store(generic)] with no generic block at all by "cannot find macro Selection in this scope ... Selection is in scope, but it is a struct, not a macro": write the block

What you seeWhyFix
store Counter has no constructor in this #[undra::api(store)] blockthe platforms create a store by calling one of its constructors, and a type takes one #[undra::api] impl block, so a constructor in another block is not seenadd pub fn new(ctx: Ctx) -> Self to this block; if Counter has a second #[undra::api] block (where the constructor is), move this block's methods into that one
Selection is a #[undra::store(generic)] but its impl block is not marked as a storethe impl block of a store must say so, so its constructors can attach the store's signals and its struct literals get the hidden cell fieldwrite #[undra::api(store, generic)] on the impl block
Todos is a #[undra::store] but its #[undra::api] impl block is not marked as a storethe impl block of a store must say so, so its constructors can attach the store's signals and its struct literals get the hidden cell fieldwrite #[undra::api(store)] on the impl block
Plain is implemented with #[undra::api(store)] but the struct has no #[undra::store]the store marker wires the constructors to the struct's signals, which only #[undra::store] sets upadd #[undra::store] to struct Plain, or remove store from the impl attribute
store Todos has no #[undra::api(store)] impl blockthe constructors of the impl block create the store and wire its signals to the platforms; without the block the store can never be instantiatedadd an impl Todos block marked #[undra::api(store)] with a constructor such as pub fn new(ctx: Ctx) -> Self
store Counter has no constructorthe platforms create a store by calling one of its constructors; without one it can never be instantiatedadd pub fn new(ctx: Ctx) -> Self to its #[undra::api(store)] impl block

E0012 trait object in a record field#

Raised by macros.

trait object in a record field (the blueprint example)

What you seeWhyFix
Vec<Box<dyn Any>> cannot cross the boundarytrait objects have no wire representationmake items a concrete #[undra::api] type, or an enum listing the cases you need

E0013 store cannot be restored automatically#

Raised by macros.

store cannot be restored automatically: it has a Computed field, or a field that is neither a signal, a Ctx, a WeakCtx nor Default, and no #[undra::store(restore = "..")] hook

What you seeWhyFix
store Todos cannot be restored automatically: count is computedrestoring a snapshot decodes the plain signals and rebuilds the store, but only your code knows how to derive computed signals from themadd #[undra::store(restore = "Self::rebuild")] with fn rebuild(ctx: Ctx, <one Signal<T> per plain signal, in order>) -> Self, the same code new uses to build the store
store Sync cannot be restored automatically: its field of type Config has no Defaultrestoring a snapshot rebuilds the store from its plain signals and fills every other field with Default::default() (a Ctx is cloned from the argument, a WeakCtx downgraded from it)implement Default for the type, or add #[undra::store(restore = "Self::rebuild")] with fn rebuild(ctx: Ctx, <one Signal<T> per plain signal, in order>) -> Self, the same code new uses to build the store

Methods#

E0020 &mut self receiver#

Raised by macros.

&mut self receiver

What you seeWhyFix
&mut self receiver on method clearobjects are shared as Arc<Type> across calls and threads, so methods only ever get &selftake &self and mutate through signals (Signal<T>), a Mutex or another form of interior mutability
&mut self receiver on method incrementobjects are shared as Arc<Type> across calls and threads, so methods only ever get &selftake &self and mutate through signals (Signal<T>), a Mutex or another form of interior mutability

E0021 self by value#

Raised by macros.

self by value

What you seeWhyFix
self by value on method finishan object is shared across calls; a method cannot consume ittake &self and clone whatever you need to keep

E0022 non-Send future in an async method: rustc's own error, pointed at the method by an assertion named after this code#

Raised by rustc, named by a macro.

non-Send future in an async method or query: rustc's own "future cannot be sent between threads safely", pointed at the method by an assertion the macros emit; the last note names the assertion, _undra_error_E0022_the_future_of_an_async_method_must_be_Send. Do not hold a non-Send value (an Rc, a RefCell borrow, a MutexGuard) across an .await

The compiler reports this one itself, so it carries no Undra code. It is pointed at the method, and the last note names the assertion the macro emitted, _undra_error_E0022_the_future_of_an_async_method_must_be_Send: the code to look up.

text
error: future cannot be sent between threads safely
  --> src/lib.rs:15:18
   |
15 |     pub async fn run(&self) -> u32 {
   |                  ^^^ future created by async block is not `Send`
   |
   = help: within `{async block@src/lib.rs:9:1: 9:10}`, the trait `Send` is not implemented for `Rc<u32>`
note: future is not `Send` as this value is used across an await
  --> src/lib.rs:17:32
   |
16 |         let local = Rc::new(1_u32);
   |             ----- has type `Rc<u32>` which is not `Send`
17 |         std::future::ready(()).await;
   |                                ^^^^^ await occurs here, with `local` maybe used later
note: required by a bound in `_undra_error_E0022_the_future_of_an_async_method_must_be_Send`
  --> src/lib.rs:9:1
   |
 9 | #[k::api]
   | ^^^^^^^^^ required by this bound in `_undra_error_E0022_the_future_of_an_async_method_must_be_Send`
   = note: this error originates in the attribute macro `k::api` (in Nightly builds, run with -Z macro-backtrace for more info)

Ports#

E0030 port method with a non-wire parameter#

Raised by macros.

port method with a non-wire parameter

What you seeWhyFix
parameter listener of port method call is not a wire typecallback Arc<dyn Listener> cannot be a parameter of a port (Listener is a callback interface) (a port is implemented once, by the platform, for the whole process; a callback instance in its arguments would need a wrapper type the port implementation does not have)pass a record or an id through the port
parameter url of port method request is not a wire type&str cannot cross the boundary (references have no wire representation; every value crosses by copy)use an owned String
parameter on_progress of port method request is not a wire typetrait object dyn Fn(u8) cannot cross the boundary (trait objects have no wire representation and no equivalent in Swift, Kotlin or TypeScript)use a concrete #[undra::api] type or an enum listing the cases you need; to call into the platform, declare a #[undra::callback] trait and take Arc<dyn Trait> as a parameter
parameter child of port method open is not a wire typeobject Arc<Child> cannot be a parameter of a port (a port implementation on the platform would receive a reference it has no wrapper type for)pass a record or an id through the port (the object here is Child)

E0031 event port method that is not a plain fn(..) returning ()#

Raised by macros, schema validation.

event port method with a return type, or that is async

What you seeWhyFix
event port method changed returns a valueevents are fire-and-forget notifications from the host; there is no reply to carry a valueremove the return type, or drop event from #[undra::port(event)] to make it a request/reply port
event port method resumed is asyncevents are fire-and-forget notifications from the host; nothing waits for themmake it a plain fn returning ()
event port Connectivity method changed returns a value or is asyncevents are fire-and-forget notifications from the host; nothing waits for them, so there is no reply to carry a valuemake the method a plain fn returning (), or make the port a request/reply port

E0032 invalid port trait shape#

Raised by macros.

invalid port trait shape (an async method on a sync port, a parameter that is not a plain name, an associated type or const, no &self receiver)

What you seeWhyFix
#[undra::port(sync)] port has the async method now_mssync promises that every method answers immediately, so the core can call it without yieldingremove async, or remove sync from the attribute
port trait Kv has an associated item that is not a methoda port is a list of methods the platform implements; associated types and constants have no wire representationremove it, or move it to a separate trait

E0033 the error type of a port method has no From<PortError>#

Raised by macros (a bound the compiler checks).

the error type of a Result port method has no From<PortError> (an unavailable port cannot be reported)

What you seeWhyFix
the error type StoreError of a method of the Store port cannot represent a port that is unavailablea port nobody registered, a cancelled call and a reply that does not decode are ordinary outcomes (SPEC 6.3), and a method that returns Result<T, E> reports them as its error instead of panicking; that needs From<PortError> for the error typeimplement From<undra::runtime::PortError> for StoreError, mapping it to a variant such as Unavailable, or to the Display text of the PortError

Queries and mutations#

E0040 query without key, mutation with stale, or another invalid query argument#

Raised by macros.

query without key / mutation with stale / a query argument of the wrong kind, an interval below one second (use a stream for real-time data), refetch_pages or persist_pages that is not a whole number of at least 1, polling or paging options on a mutation

What you seeWhyFix
interval = "500ms" is below one seconda poll fetches the whole result again each time, so a query polled more than once a second is really a stream: use a stream for real-time datawrite interval = "1s" or more, or deliver the changes with a #[undra::port] event or a stream
interval = "0s" is below one seconda poll fetches the whole result again each time, so a query polled more than once a second is really a stream: use a stream for real-time datawrite interval = "1s" or more, or deliver the changes with a #[undra::port] event or a stream
invalid interval duration: soon does not start with a whole numberinterval is how long after a fetch ends the next one startswrite a whole number and a unit, for example interval = "30s"
mutation add has intervalpolling and paging apply to cached reads; a mutation writes and caches nothingremove interval; put it on the query the mutation invalidates
query todos has no keythe cache is addressed by key: two calls share a cached result only if their keys are equaladd key = "todos", with {param} placeholders for the parameters that distinguish results
mutation add_todo has stalestale is how long a cached *read* stays fresh; a mutation writes and caches nothingremove stale; put it on the query the mutation invalidates

E0041 query or mutation function with an invalid signature#

Raised by macros.

query or mutation function with an invalid signature (not async, no ctx: &Ctx first parameter, not returning Result<T, E>, a stream result, self)

What you seeWhyFix
sync_query must be async#[undra::query] functions fetch or write through ports, which are asynchronouswrite async fn
no_ctx must take ctx: &Ctx as its first parameterthe runtime hands every query and mutation a context to reach ports and other queriesadd ctx: &Ctx (or ctx: Ctx) before the other parameters
plain must return Result<T, E>the cache stores the success value and the error separately, and the platforms show bothreturn Result<T, E> where E is a #[undra::error] enum

E0042 query whose success value is () or an Option#

Raised by macros.

query whose success value is () or an Option (a query caches a value; use a mutation for effects)

What you seeWhyFix
query ping returns ()a query caches the value it returns; a query with nothing to return has nothing to cacheuse #[undra::mutation] for a call that only has effects, or return the data the platform needs
query find returns an Optionthe handle's data signal is already optional (no result yet), so an optional result would be ambiguous: None could mean "not loaded" or "loaded, absent"return a record or a list (an empty Vec says "nothing"), or an enum naming the cases

Names in the generators#

E0050 duplicate type name, id or variant index#

Raised by schema validation.

duplicate type name, a type named like something the generated code depends on, two items with one id, two variants with one index

What you seeWhyFix
duplicate type name Todo (declared as record and again as enum)type names must be unique within a core: a type is identified to the platforms by its name (its id is a hash of it), so two declarations cannot share onerename one of the two Todo declarations, or remove the duplicate
duplicate type name Storage at the port Storage (the name is already used by a record)names and ids identify a type, a method or a variant to the platforms and in the generated code, so each must be unique within a corerename one of the two, or remove the duplicate
record Signal has a name the generated code depends onthe generated bindings use a type called Signal (a standard type of Swift, Kotlin or TypeScript, or one of the Undra runtime's), so a type of the schema with the same name would shadow itrename it, for example MySignal
duplicate type id 0x00000007 at the schema (Alpha and Beta hash to the same id)names and ids identify a type, a method or a variant to the platforms and in the generated code, so each must be unique within a corerename one of the two items: ids are hashes of the names, so a different name gives a different id
duplicate variant index 1 at enum Statusnames and ids identify a type, a method or a variant to the platforms and in the generated code, so each must be unique within a coregive every variant of the enum an index of its own
duplicate type name Todo (declared as record and again as record)type names must be unique within a core: a type is identified to the platforms by its name (its id is a hash of it), so two declarations cannot share onerename one of the two Todo declarations, or remove the duplicate

E0051 a name that collides after case conversion or is not an identifier#

Raised by schema validation.

a name that collides after case conversion (a_b and aB), shadows a member of the runtime base classes, or is not an identifier in a target language; in the iOS 15 / 16 Swift mode also a store member named objectWillChange (§10.1, ADR-045)

What you seeWhyFix
at record Todo, due_date, dueDate all become dueDatefield names are converted to camelCase, so names that differ only in case or underscores end up equalrename one of them so that they stay distinct after conversion
at object Thing, close is a name the generated code already usesthe runtime base class or the generated code already declares a member with that namerename it so that it does not meet that name
at record Todo, 1st is not a name the generated code can useevery name of the schema becomes an identifier in Swift, Kotlin and TypeScript: ASCII letters, digits and underscores, not starting with a digitrename it to letters, digits and underscores, starting with a letter
at object Counter, object_will_change becomes objectWillChange, a name the generated code already useswith the iOS 15 / 16 store shape (swift_observation = "observable-object", the default for a deployment target below iOS 17) a store is a Combine ObservableObject, which declares that member itselfrename it so that it does not meet that name
at the schema, newest<Todo>, newest_todo all become newestTodoid constants are named in camelCase in Swift and TypeScript, and the id of an instantiation of a generic function names the function and the type, so names that differ only in case or underscores end up equalrename one of them so that they stay distinct after conversion
at the schema, newest<Todo>, newest_todo all become NEWEST_TODOid constants are named UPPER_SNAKE_CASE in Kotlin, and the id of an instantiation of a generic function names the function and the type, so names that differ only in case or underscores end up equalrename one of them so that they stay distinct after conversion

E0052 an item named like a standard library item, with another id#

Raised by schema validation.

a record, enum, error, object or port named like a standard library item (section 8) but with another id: the runtimes implement the standard items under those names and ids

What you seeWhyFix
record HttpRequest has the name of an Undra standard library item but the id 0x00000007 instead of 0xbbbc6e52every platform runtime implements the standard ports and types under those names and ids, and generated code refers to them instead of declaring them, so a different item cannot share the namerename it, for example MyHttpRequest, or use the standard one from undra-ports

Type identity and the schema#

E0060 a spelling that looks like a built-in Undra type is another type#

Raised by macros (a check the compiler runs).

a spelling that looks like a built-in Undra type (Bytes, Uuid, String, Vec, ..) is a different type; reported at the field or parameter by the same-type assertion the macros emit; for a wire leaf (Uuid, Timestamp, Duration, Bytes, Decimal) by the membership assertion Spelled: WireLeaf<kind>, whose message names the leaves and the features (uuid, chrono, time, rust_decimal, bytes) that add the types of other crates (ADR-042)

What you seeWhyFix
Bytes is spelled like a built-in Undra type, but it is not onethe schema records this position as a wire leaf (Uuid, Timestamp, Duration, Bytes or Decimal), so the platforms would read the bytes of that leaf where the generated code writes Bytesrename your type, import the built-in one, or, for a type of the uuid, chrono, time, rust_decimal or bytes crate, enable that feature of undra
Uuid is spelled like a built-in Undra type, but it is not onethe schema records this position as a wire leaf (Uuid, Timestamp, Duration, Bytes or Decimal), so the platforms would read the bytes of that leaf where the generated code writes Uuidrename your type, import the built-in one, or, for a type of the uuid, chrono, time, rust_decimal or bytes crate, enable that feature of undra
Timestamp is spelled like a built-in Undra type, but it is not onethe schema records this position as a wire leaf (Uuid, Timestamp, Duration, Bytes or Decimal), so the platforms would read the bytes of that leaf where the generated code writes Timestamprename your type, import the built-in one, or, for a type of the uuid, chrono, time, rust_decimal or bytes crate, enable that feature of undra
Decimal is spelled like a built-in Undra type, but it is not onethe schema records this position as a wire leaf (Uuid, Timestamp, Duration, Bytes or Decimal), so the platforms would read the bytes of that leaf where the generated code writes Decimalrename your type, import the built-in one, or, for a type of the uuid, chrono, time, rust_decimal or bytes crate, enable that feature of undra

E0061 the name written is not the declared name of the type, or the type is not declared with #[undra::api]#

Raised by macros (a check the compiler runs).

the schema records a name that the type written there does not have: an alias of an Undra type (type Todo = Item), a renamed import (use m::Item as Todo), or a name that is not a type declared with #[undra::api] at all (a plain struct, type Id = u64); reported by a const assertion on UNDRA_TYPE_ID

What you seeWhyFix
Plain is not a type declared with #[undra::api]Undra describes a type to the platforms by the name it is written with, so the name must be a record or enum declared with #[undra::api] or an error declared with #[undra::error]; anything else, such as a plain struct or an alias (type Id = u64), has no definition the platforms could generateadd #[undra::api] to Plain, or, if it is an alias, write the type it stands for where it is used
Id is not a type declared with #[undra::api]Undra describes a type to the platforms by the name it is written with, so the name must be a record or enum declared with #[undra::api] or an error declared with #[undra::error]; anything else, such as a plain struct or an alias (type Id = u64), has no definition the platforms could generateadd #[undra::api] to Id, or, if it is an alias, write the type it stands for where it is used
Kid here is an alias or a renamed import of an object that is declared under another nameUndra describes an object to the platforms by the name it is written with, while the handle the core issues is of the type that name resolves to; with type Kid = Other or use path::Other as Kid the platforms would wrap it as Kidwrite the object under the name it is declared with (Other in the examples above)
LostPage here is an alias or a renamed import of an Undra type that is declared under another nameUndra describes a type to the platforms by the name it is written with, while the generated code encodes the type that name resolves to; with type LostPage = Other or use path::Other as LostPage the platforms would be told LostPage and receive the layout of Otherwrite the type under the name it is declared with (Other in the examples above), or declare a separate #[undra::api] struct LostPage if you mean a distinct type
Todo here is an alias or a renamed import of an Undra type that is declared under another nameUndra describes a type to the platforms by the name it is written with, while the generated code encodes the type that name resolves to; with type Todo = Other or use path::Other as Todo the platforms would be told Todo and receive the layout of Otherwrite the type under the name it is declared with (Other in the examples above), or declare a separate #[undra::api] struct Todo if you mean a distinct type
Entry here is an alias or a renamed import of an Undra type that is declared under another nameUndra describes a type to the platforms by the name it is written with, while the generated code encodes the type that name resolves to; with type Entry = Other or use path::Other as Entry the platforms would be told Entry and receive the layout of Otherwrite the type under the name it is declared with (Other in the examples above), or declare a separate #[undra::api] struct Entry if you mean a distinct type

E0062 a port call could not be answered and its method has no error channel: a runtime message#

Raised by runtime (the generated port proxy).

a port call that cannot be answered and has no error channel: no adapter registered, a cancelled call, a reply that does not decode. A method without an error channel panics with this message (the runtime contains the panic at the dispatch boundary; on wasm it traps the core); a method returning Result reports it as its error type, and HttpError::Network / FsError::Io carry the code and the link

What you seeWhyFix
the Rng port has no adapter registered (method fill)this method has no error channel, so an unavailable port cannot be reported and the call panics; the runtime contains the panic, but on the web it traps the coreregister an adapter (core.registerPort(..) in TypeScript, Kotlin and Swift, undra_port_register in C), bind a Rust implementation (undra::ports::fakes in tests), or give the method a Result<T, E> return type so it can report the outage

E0063 nested Option<Option<T>>#

Raised by macros.

Option<Option<T>> in a public position

What you seeWhyFix
nested option Option<Option<u8>> cannot cross the boundaryKotlin and TypeScript cannot express nested optionality: Some(None) and None would both arrive as nullwrap the inner option in a record or an enum that names the two cases
nested option Option<Option<i32>> cannot cross the boundaryKotlin and TypeScript cannot express nested optionality: Some(None) and None would both arrive as nullwrap the inner option in a record or an enum that names the two cases
nested option Option<Box<Option<u8>>> cannot cross the boundaryKotlin and TypeScript cannot express nested optionality: Some(None) and None would both arrive as nullwrap the inner option in a record or an enum that names the two cases

E0064 an object (#[undra::api] impl) used where a value is expected, or a value used as an object, or an object where objects may not stand (ADR-040)#

Raised by macros (a check the compiler runs), schema validation.

an object (#[undra::api] impl) used as a value (a field, a parameter or a return written Mailbox): it crosses as Arc<Mailbox> or &Mailbox; a record, enum or error written as an object (Arc<Todo>, &Todo: records cross by value); an object where objects may not stand (a record or variant field, a signal, a map key or value, a stream item, a port, callback, query or mutation value, or nested deeper than Option or Vec), with the reason and the way out of its position (ADR-040)

What you seeWhyFix
Calculator is an object and cannot be used as a valuean object lives in the core and crosses the boundary as a handle; its contents have no wire representation, so it cannot be a field, a variant field, a signal value, a map entry or a query valuereturn it as Arc<Calculator>, take it as &Calculator or Arc<Calculator> (a method, constructor or function parameter or return), or use a record with the data the platform needs
NotAnObject is not an objectan object is a type with an #[undra::api] impl block: the macro generates what lets the core hand it to the platforms as a handle, and without one there is nothing to hand outadd #[undra::api] to an impl NotAnObject { .. } block, or use a record (#[undra::api] struct) if it is plain data
object Arc<Child> cannot be a field of a record or enuma record or enum field holds a value: it is copied, compared, hashed and Codable, and none of that can carry a reference to an objectkeep the data the platform needs in the field (an id, a record), and put the child object behind a method of the parent (the object here is Child)
object Arc<Child> cannot be used herean object can only stand alone, or inside Option or Vec, as a method or function parameter or returnuse Arc<T>, Option<Arc<T>> or Vec<Arc<T>> (a parameter may also be &T or Option<&T>) (the object here is Child)
&Child cannot be an element of a lista list owns its elements, and a borrow of an object cannot outlive the call that made itwrite the list as Vec<Arc<Child>>
object Arc<Child> cannot be the result of a query or mutationquery and mutation values are cached, compared and persisted, so they must be valuesuse a record or an id, and return the object from a method that calls the query (the object here is Child)

E0065 a signal of a store written off its owning runtime's core (ADR-035): a runtime message#

Raised by runtime (the write check of undra-signals).

a signal of a store was written from a thread that does not hold the owning runtime's core lock: a blocking-pool worker, a host or embedder thread, a thread inside no runtime, or another runtime's core. A panic with this message, in every build; Signal::try_set / try_update return it as WriteError::OffCore (ADR-035)

What you seeWhyFix
a signal of a store owned by runtime 5 was written from a thread that does not hold its core locksignal writes belong on the core: the runtime delivers each change-set to its host in commit order under its core lock, so a write from any other thread (a blocking-pool worker, a host or embedder thread, another runtime's core) would be delivered unordered, to the wrong host, or not at allreturn the value to the task or call that awaits it (ctx.spawn, a dispatched call, the result of spawn_blocking), or wrap the write in ctx.with_core(|| ..) on a host thread; Signal::try_set reports this as a WriteError instead of panicking

E0066 a #[undra::migrate] hook with a wrong target or shape (ADR-037; addition)#

Raised by macros, runtime (start-up check of the registered hooks).

a #[undra::migrate] hook with a wrong target or shape (ADR-037): no target or more than one, signal without store, a from that is not a 64-bit hex fingerprint, a function that is not a plain non-generic fn taking the target's old value (&DynValue, Option<&DynValue> or &DynRecord) and returning Result<_, MigrateError>, a ty = "X" hook that does not return the #[undra::api] type X (a const assertion the compiler runs); a store, signal or mutation the core does not have, or a signal hook returning another type than the signal's, is logged at ERROR with this code when a runtime starts (the macro cannot see those items)

What you seeWhyFix
#[undra::migrate] needs a targeta migration hook converts persisted data of one record or enum, one signal of one store, or one mutation's queued input to this build's types; the runtime finds it by that target and calls it with the old value in a fixed shapename exactly one target: ty = "Todo", store = "Profile", signal = "age" or mutation = "add_todo"
#[undra::migrate] names more than one targeta migration hook converts persisted data of one record or enum, one signal of one store, or one mutation's queued input to this build's types; the runtime finds it by that target and calls it with the old value in a fixed shapename exactly one target: ty = "Todo", store = "Profile", signal = "age" or mutation = "add_todo"
signal = ".." needs store = ".."a migration hook converts persisted data of one record or enum, one signal of one store, or one mutation's queued input to this build's types; the runtime finds it by that target and calls it with the old value in a fixed shapename the store the signal belongs to: store = "Profile", signal = "age"
the migration hook wrong_parameter must take one parameter, old: Option<&DynValue>a migration hook converts persisted data of one record or enum, one signal of one store, or one mutation's queued input to this build's types; the runtime finds it by that target and calls it with the old value in a fixed shapewrite fn wrong_parameter(old: Option<&DynValue>) -> Result<T, MigrateError>, where T is the signal's value type (old is None when the snapshot lacks the signal): a plain, non-generic, non-async function
the migration hook wrong_return must return Result<DynRecord, MigrateError>a migration hook converts persisted data of one record or enum, one signal of one store, or one mutation's queued input to this build's types; the runtime finds it by that target and calls it with the old value in a fixed shapewrite fn wrong_return(old: &DynRecord) -> Result<DynRecord, MigrateError>: a plain, non-generic, non-async function
from = "not-hex" is not a fingerprinta migration hook converts persisted data of one record or enum, one signal of one store, or one mutation's queued input to this build's types; the runtime finds it by that target and calls it with the old value in a fixed shapewrite the 64-bit fingerprint of the old type in hex, as the runtime's log or undra.types.<fingerprint> key shows it: from = "0x0123456789abcdef", or leave from out to take every old version

E0070 a named instantiation of a generic data type that is declared twice or outside the crate of its template#

Raised by macros (a check the compiler runs).

a named instantiation of a generic data type, object or store (type TodoPage = Page<Todo>, type TodoSelection = Selection<Todo>) declared twice, or outside the crate of its template (ADR-042, ADR-058; for an object or a store a module-level constant _undra_error_E0070_this_instantiation_of_Selection_Todo_is_declared_twice_keep_one_alias_per_instantiation makes a second alias in the same module the first error rustc reports): the inherent impl of the instantiation carries a constant named after the rule (_undra_error_E0070_this_instantiation_of_Page_is_declared_twice_keep_one_alias_per_instantiation), so a second alias of one instantiation is reported by rustc as that constant defined twice; an alias in another crate than its template's is reported by the macro itself, naming both crates

What you seeWhyFix
TodoPage instantiates Page, which is declared in the crate model, not in appan instantiation adds an inherent impl to the template's type, which only the crate that declares the template may do, and a second crate naming the same instantiation would register it twicedeclare the alias next to the template, in model, and use it from here; or declare a concrete #[undra::api] struct or enum in this crate

E0071 a method of a #[undra::callback] trait that is neither fire-and-forget nor async with a Result, or whose name starts with __ (ADR-041)#

Raised by macros, schema validation.

a method of a #[undra::callback] trait that returns a value synchronously, is async without a Result, whose name starts with __ (reserved for __release and __cancel), or an async method marked #[undra(coalesce)] (ADR-041): the host runs a callback outside the core's thread and lock, so the core can never wait for it, and a host can always fail or be gone; a method reports (fn m(&self, ..)) or is async and returns Result<T, E>

What you seeWhyFix
callback method token returns a value synchronouslythe host runs a callback outside the core's thread and lock, so the core can never wait for it synchronously, and a host implementation can always fail or be gonemake it async and return Result<T, E>, or make it a plain fn that returns nothing
callback method ask is async and returns nothingthe host runs a callback outside the core's thread and lock, so the core can never wait for it synchronously, and a host implementation can always fail or be gonereturn Result<T, E> (an #[undra::error] enum that implements From<PortError>), or remove async to make it a fire-and-forget report
callback method count is async but does not return a Resultthe host runs a callback outside the core's thread and lock, so the core can never wait for it synchronously, and a host implementation can always fail or be gonereturn Result<T, E> so the method can report that the host failed or is gone
#[undra(coalesce)] on the async callback method confirmcoalesce drops the older of two pending calls, and an async method's caller is waiting for each answerremove #[undra(coalesce)], or make the method a plain fn that reports progress
callback method __release has a reserved namenames that start with __ belong to the protocol (__release gives an instance back, __cancel cancels a call): a method of that name would be mistaken for onerename the method
method token of the callback interface Provider returns a value synchronously: make it async and return a Result<T, E>the host runs a callback outside the core's thread and lock, so the core can never wait for it synchronously, and a host implementation can always fail or be gone: a method either reports (fire-and-forget, returning nothing) or is async and returns a Resultmake a reporting method return (), or make a method that answers async and return Result<T, E>; do not start a name with __

E0072 the instantiation list of a generic function or method (generic(T = [Todo, Note])) is empty, repeats a type, lists something that is not a named value type, names a type parameter the function does not have, or the function has several type parameters; a schema whose generic labels do not describe their definitions (ADR-058; addition)#

Raised by macros, schema validation.

the instantiation list of a generic function or method (ADR-058): a list for a parameter the function does not have, an empty list, a type listed twice, a type that is not a named value type (Vec<Todo>, a scalar, String, a leaf type, Arc<Mailbox>, an object: a const assertion the compiler runs says so for a plain name that turns out to be an object), a function with two type parameters; in the schema a generic label that does not describe its definition (the name is not of<Type>, the argument is not a record or an enum of the schema, a constructor or port method carries a label) or definitions that share one of but are not one function with one type replaced (a different parameter list, is_async, takes_ctx, inferred flag, parameter name or type shape with the names erased)

What you seeWhyFix
generic(U = [..]) on wrong_parameter, which has no type parameter Uthe list says which types a type parameter of the function is instantiated with; wrong_parameter declares Twrite generic(T = [Todo, Note])
generic(T = [..]) on no_parameter, which has no type parameter Tthe list says which types a type parameter of the function is instantiated with; no_parameter declares noneremove generic(..), or add the type parameter
the list of T on empty is emptya generic function crosses once per listed type; with no type it would not cross at alllist at least one type, generic(T = [Todo]), or remove #[undra::api] if the function is not for the platforms
Todo is listed twice for T on repeatedeach listed type becomes one function, repeated<Todo>, and two functions cannot share that nameremove one of them
Vec<Todo> cannot be listed for T on unnamedeach instantiation is presented under the name of its type (draft(Todo.self) in Swift, draft(Todo::class) in Kotlin, draft("Todo") in TypeScript), so a listed type is a value type declared with #[undra::api]: a record, an enum, a newtype or a named instantiationlist the element type and write Vec<T> in the signature, or give the type a name: #[undra::api] pub struct Todos(pub Vec<Todo>);
u32 cannot be listed for T on unnamedeach instantiation is presented under the name of its type (draft(Todo.self) in Swift, draft(Todo::class) in Kotlin, draft("Todo") in TypeScript), so a listed type is a value type declared with #[undra::api]: a record, an enum, a newtype or a named instantiationlist the element type and write Vec<T> in the signature, or give the type a name: #[undra::api] pub struct Todos(pub Vec<Todo>);

E0073 an infinite query that does not meet ADR-043's shape: no item_key or one that names no field of the rows, no or more than one #[undra(cursor)] parameter, a cursor that is not Option<C> or is in the key, a success type that is not Page<T, C>, rows that are not a record#

Raised by macros, schema validation.

an infinite query (ADR-043) that is not a list of records with a cursor: no item_key, or one that names no field of the rows; no or more than one #[undra(cursor)] parameter, a cursor that is not Option<C> or is part of the key; a success type that is not Page<T, C> (with C the cursor's type) or rows that are not a record; item_key, refetch_pages or persist_pages without infinite, persist_pages without persist, #[undra(cursor)] on a query that is not infinite; in the schema an infinite mutation or a returns that is not Vec<T> of a record with the item_key field: the handle shows the pages as one list keyed by a field of its rows, and each page is asked for with the cursor the previous one returned

What you seeWhyFix
the infinite query no_cursor has no #[undra(cursor)] parameterthe core asks for each page with the cursor the previous one returned: exactly one parameter carries it, None for the first pagemark one parameter #[undra(cursor)] cursor: Option<String> (or the cursor type your server uses)
the infinite query two_cursors has 2 #[undra(cursor)] parametersthe core asks for each page with the cursor the previous one returned: exactly one parameter carries it, None for the first pagemark one parameter #[undra(cursor)] cursor: Option<String> (or the cursor type your server uses)
the cursor cursor of not_an_option is String, not an Option<C>the cursor is None for the first page and the previous page's next after itwrite #[undra(cursor)] cursor: Option<String>, or another value type for the cursor your server uses
the cursor cursor is in the key of the infinite query in_the_keyevery page of one list shares one cache entry, so the cursor, which differs per page, cannot be part of its keyremove the placeholder from key; the key holds the parameters that distinguish lists
#[undra(cursor)] on cursor, which is not a parameter of an infinite querythe cursor is how an infinite query asks for its next page; an ordinary query has no pagesremove the attribute, or add infinite and item_key = ".." to the query
item_key = "idd" of the infinite query typo names no field of Postitem_key names the field of the rows that identifies them, and Post has the fields id, titlewrite the name of one of those fields as item_key

E0074 the impl block of a generic object that is not for the type with its own type parameters, each exactly once, or a method of a generic object with type parameters of its own (ADR-058; addition)#

Raised by macros.

the impl block of a generic object (ADR-058) that is not for the type with its own type parameters, each exactly once (impl<T> Cache<Vec<T>>, impl<T> Cache<T, Todo>, a parameter applied twice or not at all), or a method of a generic object that has type parameters of its own, with or without a generic(..) list: an instantiation is one class on each platform, and a second level of generics would multiply every one of them

What you seeWhyFix
the impl block of the generic object Cache is for Cache<Vec<T>>a generic object is instantiated by naming its type arguments (pub type TodoCache = Cache<Todo>;), so its block is for the type with its own parameters, each exactly oncewrite impl<T> Cache<T> and put the type you meant in the methods' types
the impl block of the generic object Pair is for Pair<A, Todo>a generic object is instantiated by naming its type arguments (pub type TodoPair = Pair<Todo, Tag>;), so its block is for the type with its own parameters, each exactly oncewrite impl<A, B> Pair<A, B> and put the type you meant in the methods' types
the impl block of the generic object Twin is for Twin<A, A>a generic object is instantiated by naming its type arguments (pub type TodoTwin = Twin<Todo, Tag>;), so its block is for the type with its own parameters, each exactly oncewrite impl<A, B> Twin<A, B> and put the type you meant in the methods' types
generic(..) on convert, a method of the generic object Box2an instantiation of a generic object is one class on each platform; a type parameter on a method would multiply every instantiation by itmake the parameter a type parameter of the object and name it in the alias, or write the method for a concrete type
generic parameter U on map, a method of the generic object Box2an instantiation of a generic object is one class on each platform; a type parameter on a method would multiply every instantiation by itmake the parameter a type parameter of the object and name it in the alias, or write the method for a concrete type

The command line#

C0001 no undra.toml from start up to the filesystem root#

Raised by undra.

not inside an Undra project: no undra.toml from the working directory up to the filesystem root

What you seeWhyFix
no undra.toml found in <dir> or any parent directorythis command works on an Undra project, and a project is the directory that holds undra.tomlrun it inside a project, point at one with -C <dir>, or create one with undra init <name>

C0002 a configuration or schema file is unusable#

Raised by undra.

undra.toml or a schema file cannot be read or has a value the CLI cannot use

What you seeWhyFix
<dir>/undra.toml: line 2: name in [project] is an integer but must be a stringthe file drives the build, so a value the CLI cannot understand would make it guesswrite it as a string, for example name = "text"

C0003 a tool is not installed#

Raised by undra.

a tool the command needs is not installed or not on PATH

What you seeWhyFix
cargo was not foundreading the core crate needs cargo, and it is not on your PATHinstall Rust with rustup: https://rustup.rs (then open a new terminal) run undra doctor to check the rest of the toolchain

C0004 a build tool exited with a failure#

Raised by undra.

a build tool ran and failed; its own output follows the diagnostic

What you seeWhyFix
cargo metadata failed while reading the core crate (exit status: 101)the tool's own output above says what it objected to; Undra cannot continue without its resultfix the problem the tool reported and run the command again; undra doctor checks the toolchain

C0005 the core crate is missing, or is not an Undra core#

Raised by undra.

the core crate is missing, or is not an Undra core

What you seeWhyFix
the core crate c0005-core does not depend on Undrawithout the undra crate there are no #[undra::api] items to describe, and the schema would be emptyadd undra = "0.1" to the core's [dependencies] (or a path to your Undra checkout)

C0006 the schema could not be extracted from the built core#

Raised by undra.

the schema could not be extracted from the built core

The command prints this diagnostic with the details of the failure that caused it.

C0007 the schema cannot be turned into bindings (bindgen diagnostics)#

Raised by undra.

the schema cannot be turned into bindings (the E0001, E0005, E0006, E0010, E0011, E0031, E0050, E0051, E0052 and E0072 diagnostics of schema validation follow)

What you seeWhyFix
the schema cannot be turned into bindings (1 problem)the public surface of the core has to be expressible in Swift, Kotlin and TypeScript, and these items are notchange the items named below in the core (each message says what to do), then run undra bindgen again

C0008 the command would overwrite something it must not#

Raised by undra.

undra init or undra adopt would write into a directory that already has files in it

What you seeWhyFix
<dir>/taken already exists and is not emptyundra init creates a new project and will not write into a directory that has files in itchoose another name, or another parent with --dir; to add Undra to an existing app use undra adopt <dir>/taken

C0009 an argument is unusable#

Raised by undra.

an argument has a value the command cannot use

What you seeWhyFix
HEAD has no schema.json--against compares the schema file committed at the ref with the one in the working tree, so the ref has to have itcommit the schema file there (undra schema export -o schema.json), name another file, or compare two files (undra schema diff old.json new.json)
my app cannot be a project name: it contains characters other than ASCII letters, digits, - and _the name becomes a Cargo package (<name>-core), a Swift module and a Kotlin package, which are stricter than file nameschoose a name like todo-app or acme_notes you can still call the folder anything: undra init my-app --dir <parent>

C0010 an I/O operation failed#

Raised by undra.

a file or directory operation failed

What you seeWhyFix
could not create <dir>/afile/demo: Not a directory (os error 20)the command needs to read or write this path and the operating system refusedcheck that the path exists and that you may access it, then run the command again

C0011 the Rust toolchain lacks a compilation target#

Raised by undra.

the Rust toolchain lacks a compilation target the build needs

What you seeWhyFix
the Rust target wasm32-unknown-unknown is not installedbuilding for this platform needs the standard library compiled for it, and rustup has not installed itrustup target add wasm32-unknown-unknown

C0012 the platform is not available on this machine#

Raised by undra.

the platform is not available on this machine

The command prints this diagnostic with the details of the failure that caused it.

C0013 the dev server failed to start or crashed#

Raised by undra.

the dev server failed to start or crashed

The command prints this diagnostic with the details of the failure that caused it.

C0014 the project's Undra does not match: the core's comes from elsewhere, or it is newer#

Raised by undra.

the core and the project disagree about where Undra comes from, or the project is on a newer Undra than this undra (undra upgrade moves a project forward only)

What you seeWhyFix
core/Cargo.toml pins Undra at tag v999.0.0, newer than this undra (<version>)undra upgrade moves a project forward only, and a CLI older than the project's runtimes would generate bindings they do not match (ahead is <dir>/ahead)update this undra first (curl -fsSL https://shreypdev.github.io/undra/install.sh | sh, or cargo install --locked --force --git https://github.com/shreypdev/undra undra-cli if you installed it with cargo) and run undra upgrade again
undra.toml says Undra is at /somewhere/else, but the core's undra dependency is at <repo>the library Undra ships is built from the same Undra as the core, and the platform runtimes come from [undra] path; if they differ, the core and the apps would speak different wire formatsmake them agree: set path of the core's undra dependency and [undra] path in undra.toml to the same checkout (or remove [undra] path to use released runtimes)

Runtime messages#

The JavaScript runtime (@undra/runtime) throws and logs these. Its production build (what vite build, webpack in production mode and anything else that asks for neither the development nor the react-native condition resolve) says a code, the values and a link instead of a sentence, so a page does not carry the prose of an error whose class, kind and fields it already has: T0017: callSync, remote; see https://shreypdev.github.io/undra/docs/errors.html#T0017. Its development build (Vite's dev server, Vitest, React Native) says the sentence. Both throw the same classes with the same kind and fields; only message differs, so nothing a program can branch on changes. Text the runtime hands on as data, the field of a port's typed error (which the core receives) and a WebSocket close frame's reason (which the peer receives), is not a message: it is the same sentence in both builds. Codes are never reused.

The T codes (166)#

The sentence is what the development build says; {0}, {1}, ... are the values the production message lists, in that order.

CodeThe development build saysRaised by
T0001unknown {0} variant: {1}adapters/codecs.ts: TypeError; adapters/events.ts: RangeError
T0002unknown WsMessage variant: {0}adapters/codecs.ts: TypeError
T0003unknown WsError variant: {0}adapters/codecs.ts: TypeError
T0004unknown SseError variant: {0}adapters/codecs.ts: TypeError
T0005unknown DbValue variant: {0}adapters/codecs.ts: TypeError
T0006unknown DbError variant: {0}adapters/codecs.ts: TypeError
T0018namespace {0} is not [a-z][a-z0-9_]{0,31}adapters/names.ts: UndraError("options")
T0019Rng.fill: {0} bytes requested, the limit is {1}adapters/ports.ts: RangeError
T0020{0}: {1} ({2})adapters/ports.ts: log
T0024WebCrypto is required (crypto.getRandomValues)adapters/system.ts: VariableDeclaration
T0025a typed error that does not decode ({0} bytes)call-error.ts: UndraCallError.Malformed
T0026a stream without an error type ended with a typed error item ({0} bytes)call-error.ts: UndraCallError.Malformed
T0027an unexpected failure: {0}call-error.ts: UndraCallError.Malformed
T0028the Undra core cancelled the call (a restore replaced its object, or the core shut down)call-error.ts: super("cancelledByCore")
T0029the Undra core panicked: {0}call-error.ts: super("panicked")
T0030the Undra core refused the call: {0}call-error.ts: super("refused")
T0031the Undra core is unavailable: {0}call-error.ts: super("unavailable")
T0032the Undra core sent a reply the bindings cannot read: {0}call-error.ts: BinaryExpression
T0033{0} failed: {1}call-error.ts: super("unhandled"); worker.ts: log
T0034the reply does not decode: {0}call-error.ts: UndraCallError.Malformed
T0035a port implementation's typed failure reached a callcall-error.ts: UndraCallError.Malformed
T0036the core answered with a typed error, but this method has none ({0} bytes)call-error.ts: UndraCallError.Malformed
T0037the core opened a stream where a single reply was expectedcall-error.ts: UndraCallError.Malformed
T0038the core answered with status {0} as a failurecall-error.ts: UndraCallError.Malformed
T0039u64 out of range: {0}call-head.ts: RangeError
T0040a bare CallTarget must be FreeFunction; pass { target, handle } for a methodcall-head.ts: TypeError
T0041u32 out of range: {0}call-head.ts: RangeError
T0042the callback's target was garbage-collectedcallbacks.ts: UndraError("state")
T0043callback instance {0} was released more often than it was lentcallbacks.ts: UndraError("state")
T0044the core is not loaded: load it at app startup (the bindings' Undra<Namespace>.load(...), or UndraCore.load(...)), before creating any Undra object, or pass a core explicitlycore.ts: VariableDeclaration
T0045The operation was abortedcore.ts: Error
T0046a core was used while it is not loaded (before its load(...) succeeded, or after it was closed); calls on it reject with UndraCallError.Unavailable. Load the core at app startup, before creating any Undra object.core.ts: log
T0047mode 'wasm-main' needs the wasm optioncore.ts: UndraError("options")
T0048import failed: {0}core.ts: log
T0049unknown mode '{0}'core.ts: UndraError("options")
T0050the core is closedcore.ts: PropertyDeclaration; core.ts: UndraTransportError("closed"); transport/wasm-main.ts: UndraTransportError("closed"); ...
T0051the core returned a truncated replycore.ts: UndraTransportError("protocol")
T0052the core returned the null handle for a constructorcore.ts: UndraTransportError("protocol")
T0053{0} (the connection to the core is down: see UndraCore.connection)core.ts: log
T0054the onError handler threw while handling "{0}": {1}core.ts: log
T0055the core was closedcore.ts: UndraTransportError("closed")
T0056the core sent a truncated replycore.ts: UndraTransportError("protocol")
T0057the core sent reply status {0}core.ts: UndraTransportError("protocol"); stream-support.ts: UndraTransportError("protocol")
T0058this method is a stream; call it with UndraCore.streamcore.ts: UndraError("state")
T0084the dev server no longer has this core's objects (it was restarted, or the session expired); load a new coreerrors-rare.ts: Parameter
T0085the Undra core rejected the snapshot (code {0}); a rejected restore leaves the core unchangederrors-rare.ts: super("restore")
T0086the call failed with a typed errorerrors.ts: ReturnStatement
T0087the core panickederrors.ts: ConditionalExpression
T0088the core panicked: {0}errors.ts: ConditionalExpression
T0089the call was cancellederrors.ts: ReturnStatement
T0090the core rejected the requesterrors.ts: ConditionalExpression
T0091the core rejected the request: {0}errors.ts: ConditionalExpression
T0092unexpected reply status {0}errors.ts: ReturnStatement
T0093{0} is not available in mode '{1}'errors.ts: super("mode")
T0094schema mismatch: the bindings expect {0} but the core reports {1}; regenerate the bindings or rebuild the coreerrors.ts: super("schemaMismatch")
T0095typed port failureerrors.ts: super("port")
T0096the core sent the null handle where an object was expectedidentity.ts: UndraTransportError("protocol")
T0097the core sent option tag {0}identity.ts: UndraTransportError("protocol")
T0098{0} belongs to another core: pass an object of the core the call goes toidentity.ts: UndraCallError.Refused
T0099{0} must be an integer between 1 and {1}, not {2}lazy.ts: RangeError
T0100a lazy list was invalidated before its value (and so its page server) reached the hostlazy.ts: UndraTransportError("protocol")
T0101the core sent {0} rows for page {1} of a list of {2}, which holds {3}lazy.ts: UndraTransportError("protocol")
T0102the core sent a list length of {0} at version {1}, which it told us had {2}lazy.ts: UndraTransportError("protocol")
T0103the core keeps answering page {0} at version {1}, older than the list's {2}lazy.ts: UndraTransportError("protocol")
T0104no change-set arrived for signal {0} of handle {1} within {2} ms; is the handle a live store?mirror-waiters.ts: UndraError("observe")
T0105handle {0} is already registered with the mirrormirror.ts: UndraError("state")
T0106the mirror applied {0} rounds of change-sets in one flush: a signal subscriber keeps causing changes to a store it observesmirror.ts: UndraError("state")
T0107a keyed patch for signal {0} of handle {1} has no operation count; the signal is re-observedmirror.ts: UndraError("state")
T0108this mirror has no observe waiters: a core installs them for a transport that answers later; for any other mirror call mirrorWaiters(mirror) (from @undra/runtime) once, before whenObservedmirror.ts: UndraError("state")
T0109{0} needs Node; this is not Nodenode-builtin.ts: ConditionalExpression
T0110{0} needs Node 20.16 or 22.3 or later (process.getBuiltinModule); this is Node {1}node-builtin.ts: ConditionalExpression
T0111this Node has no {0}node-builtin.ts: Error
T0112the runtime's {0} could not be loaded: {1}on-demand.ts: UndraTransportError("closed")
T0113{0} method 0x{1}port-dispatch.ts: ReturnStatement
T0122the events of this stream were already takenrealtime/fetch-sse.ts: TypeError
T0128the messages of this connection were already takenrealtime/inbox.ts: TypeError
T0129a next() is already pendingrealtime/inbox.ts: TypeError
T0130ByteQueue.at past the endrealtime/node-websocket.ts: RangeError
T0156the wasm core trapped and was restarted from its last snapshot; this call may or may not have run before the trap, and it is not retried ({0})recovery.ts: UndraTransportError("restarted")
T0157the wasm core trapped ({0}) and was restarted from no snapshotrecovery.ts: BinaryExpression
T0158a snapshot of {0} bytes was not kept for crash recovery: it is larger than maxSnapshotBytes ({1}); the previous one stays (said once)recovery.ts: log
T0159a snapshot for crash recovery failed: {0}recovery.ts: log
T0160the core refused its last snapshot (code {0}) after the restart; it runs without its storesrecovery.ts: log
T0161this crashRecovery() already belongs to a core: make one per corerecovery.ts: UndraTransportError("unsupported")
T0162the wasm core is restarting after a traprecovery.ts: UndraTransportError("restarted")
T0163the wasm core could not be restarted: {0}recovery.ts: this.#log
T0164{0}: {1} call(s) in flight failed, {2} object(s) went stalerecovery.ts: this.#log
T0165the onCoreRestarted handler threw: {0}recovery.ts: this.#log
T0168the core answered a stream call with a plain resultstream-support.ts: UndraTransportError("protocol")
T0169the core sent a truncated stream itemstream-support.ts: UndraTransportError("protocol")
T0170the core sent a malformed stream failure: {0}stream-support.ts: UndraTransportError("protocol")
T0171the core sent stream flag {0}stream-support.ts: UndraTransportError("protocol")
T0172could not grant stream creditstream.ts: UndraError("state")
T0173adapters.{0} are ignored in wasm-worker mode: set them in LoadOptions.worker.portstransport/framed.ts: log
T0174the connection to the core was lost ({0}); reconnectingtransport/framed.ts: UndraTransportError("closed")
T0175this platform has no WebSocket; pass webSocket to use another implementationtransport/remote.ts: UndraTransportError("unsupported")
T0176could not connect to {0}: {1}transport/remote.ts: UndraTransportError("handshake")
T0177could not send Hello: {0}transport/remote.ts: UndraTransportError("handshake")
T0178the core sent a text message; Undra speaks binary envelopestransport/remote.ts: UndraTransportError("protocol")
T0179the connection to {0} closed (code {1}{2})transport/remote.ts: VariableDeclaration
T0180{0} before the core answered Hellotransport/remote.ts: UndraTransportError("handshake")
T0181could not connect to {0}transport/remote.ts: UndraTransportError("handshake")
T0182{0} did not complete the Hello exchange within {1} mstransport/remote.ts: UndraTransportError("timeout")
T0183the connection is closedtransport/remote.ts: ConditionalExpression
T0184the core is not connectedtransport/remote.ts: ConditionalExpression
T0185the core is not connected: reconnectingtransport/remote.ts: ConditionalExpression
T0186expected Hello from the core, got {0}transport/remote.ts: UndraTransportError("handshake")
T0187bad Hello from the core: {0}transport/remote.ts: UndraTransportError("handshake")
T0188bad message from the core: {0}transport/remote.ts: UndraTransportError("protocol")
T0189mode 'remote' needs the url optiontransport/remote.ts: UndraError("options")
T0190cannot send a {0} message to a wasm coretransport/wasm-main-transport.ts: UndraTransportError("protocol")
T0191the core refused the call (undra_call returned {0})transport/wasm-main.ts: encodeValue
T0192undra_alloc({0}) returned 0 instead of trappingtransport/wasm-main.ts: Error
T0193WebAssembly is not available on this platformtransport/wasm-main.ts: UndraTransportError("unsupported")
T0194GET {0} answered {1}transport/wasm-main.ts: Error
T0195could not instantiate the wasm core: {0}transport/wasm-main.ts: UndraTransportError("handshake")
T0196the module is not an Undra core: it does not export {0}transport/wasm-main.ts: UndraTransportError("handshake")
T0197the core speaks wasm ABI {0}, this runtime speaks {1}transport/wasm-main.ts: UndraTransportError("handshake")
T0198undra_init failed with code {0}transport/wasm-main.ts: UndraTransportError("handshake")
T0199the core handed out [{0}, {1}) beyond its {2} bytes of memorytransport/wasm-main.ts: RangeError
T0200the core returned a null UndraBuftransport/wasm-main.ts: UndraTransportError("protocol")
T0201the core is not startedtransport/wasm-main.ts: ConditionalExpression; transport/wasm-worker.ts: ConditionalExpression
T0202the wasm core trapped: {0}transport/wasm-main.ts: UndraTransportError("trap")
T0203the core does not export undra_snapshottransport/wasm-main.ts: UndraTransportError("unsupported")
T0204the core does not export undra_restoretransport/wasm-main.ts: UndraTransportError("unsupported")
T0205the worker gave an incomplete answertransport/wasm-worker.ts: UndraTransportError("protocol")
T0206worker.ports needs this @undra/runtime's worker script (protocol 3)transport/wasm-worker.ts: UndraTransportError("unsupported")
T0207the worker sent an envelopes message without a list of envelopestransport/wasm-worker.ts: UndraTransportError("protocol")
T0208worker error: {0}transport/wasm-worker.ts: UndraTransportError
T0209the worker sent a message that could not be deserialisedtransport/wasm-worker.ts: UndraTransportError("protocol")
T0210the worker did not start within {0} mstransport/wasm-worker.ts: UndraTransportError("timeout")
T0211could not reach the worker: {0}transport/wasm-worker.ts: UndraTransportError("handshake"); transport/wasm-worker.ts: UndraTransportError("closed")
T0212the worker script cannot {0}: rebuild it with this @undra/runtimetransport/wasm-worker.ts: UndraTransportError("unsupported")
T0213this platform has no Worker; pass worker to run the core on onetransport/wasm-worker.ts: UndraTransportError("unsupported")
T0214bad message from the worker: {0}transport/wasm-worker.ts: UndraTransportError("protocol")
T0215{0} is synchronous: in wasm-worker mode, register it in LoadOptions.worker.portstransport/wasm-worker.ts: ReturnStatement
T0216mode 'wasm-worker' needs the wasm optiontransport/wasm-worker.ts: UndraError("options")
T0217a decimal's scale is an integer from 0 to {0}, got {1}wire/decimal.ts: RangeError
T0218a decimal's mantissa must fit a signed 128-bit integerwire/decimal.ts: RangeError
T0219not a decimal: {0}wire/decimal.ts: SyntaxError
T0220unknown envelope kind: {0}wire/envelope.ts: RangeError
T0221envelope seq out of range: {0}wire/envelope.ts: RangeError
T0222envelope schema hash out of range: {0}wire/envelope.ts: RangeError
T0223raw length out of range: {0}wire/reader.ts: RangeError
T0224handle index out of range: {0}wire/types.ts: RangeError
T0225handle generation out of range: {0}wire/types.ts: RangeError
T0226handle out of range: {0}wire/types.ts: RangeError
T0227cannot convert an invalid Date to a Timestampwire/types.ts: RangeError
T0228timestamp {0} is outside the range of a Datewire/types.ts: RangeError
T0229duration must be finite: {0}wire/types.ts: RangeError
T0230duration exceeds i64 nanoseconds: {0} mswire/types.ts: RangeError
T0231invalid UUID "{0}": expected 8-4-4-4-12 hex digits (36 characters) and room for 16 bytes at offset {1} of {2}wire/types.ts: RangeError
T0232need 16 bytes for a UUID at offset {0} of {1}wire/types.ts: RangeError
T0233{0} out of range: {1}wire/writer.ts: RangeError
T0234the worker could not import the ports module {0}: {1}worker.ts: UndraTransportError("handshake")
T0235the default export of the ports module {0} must map port ids to implementationsworker.ts: UndraTransportError("handshake")
T0236the ports module {0} maps {1} to something that is not a port implementation ({ sync, methods }, as registerPort takes)worker.ts: UndraTransportError("handshake")
T0237the worker's transport cannot snapshot or restoreworker.ts: UndraTransportError("unsupported")
T0238{0} port 0x{1} could not release what it held: {2}worker.ts: log
T0239could not deliver a port reply: {0}worker.ts: log
T0240internal error: {0}worker.ts: log
T0241dropped a malformed envelope from the host: {0}worker.ts: log
T0242the worker was not started with recoveryworker.ts: UndraTransportError("unsupported")
T0243the wasm core trapped ({0}) and was restarted from a snapshot {1} ms oldrecovery.ts: UndraCoreRestarted
T0244keyed patch operation #{0} ({1}) index {2} is out of bounds for a list of length {3}wire/errors.ts: PatchError
T0246the transport passes {0} as calls but not {1}: a transport has all seven control methods (observe, release, cancel, streamCredit, event, timerFired, portReply) or none, and send frames themtransport/framed.ts: UndraError("options")

Wire failures#

A WireError says its code and fields in a production build (wire: code=unexpected_eof at=12 needed=3; see link); the development build says the sentence below, with the values in braces.

CodeThe development build says
unexpected_eofunexpected end of input at offset {at}: needed {needed} more byte(s)
invalid_utf8invalid UTF-8 in string at offset {at}
invalid_taginvalid {ty} tag {tag} at offset {at}
length_too_largelength {len} at offset {at} exceeds the available input
trailing_bytes{count} trailing byte(s) after the end of the message
bad_magicbad magic: envelope does not start with 554e4452
unsupported_versionunsupported wire version {version}
schema_mismatchschema mismatch: expected 0x{expected}, got 0x{got}
duplicate_keyduplicate map key at offset {at}
negative_durationnegative duration ({nanos} ns)
unsafe_integerinteger {value} at offset {at} is outside the JS safe integer range

Generated by site/scripts/build-errors.mjs from docs/SPEC.md section 12, the compile-fail tests of the macros crate and the message goldens of the other crates. To change a message, change the code that raises it and regenerate its golden; to change the catalogue, change the specification.

Generated from the specification and the macro tests: edit those, not this page.