Documentation menu

Error codes

Development builds of @gyral/core print each diagnostic in full. Production builds print a short line instead, so the message texts stay out of your bundle: Gyral, the code, the message’s arguments in order, and a link to this page.

Gyral G0010 my-cart Add https://gyral.dev/errors/#G0010

Read that one as: <my-cart> has no update for the message Add. Find the code below; its message shows where each argument goes. For the full sentence, reproduce the problem in development (the dev server, tests, or a build with --mode development). A hydration mismatch keeps its own sentence in production and ends with its code and link.

The codes and messages are read from @gyral/core 0.3.6, the version this site is built with; codes are never reused.

Components

G0001

<{tag}> is a browser element (render it on the server with @gyral/ssr).

Arguments: tag.

Outside the browser, define() only records your component for the server renderer, so there is no element class to construct: new MyElement() on the server throws this.

Fix: Render the component on the server through @gyral/ssr (renderPage, renderToString), instead of constructing it.

G0010

<{tag}> has no update for message "{message}".

Arguments: tag, message.

A component received a message whose _tag has no reducer in its update, so the message was dropped. It is usually a typo, or a reducer you forgot.

Fix: Add a reducer for the message to the component’s update, or stop sending it.

G0011

<{tag}> has no intent parser for data-intent="{intent}".

Arguments: tag, intent.

An event reached an element whose data-intent names an intent the component has no parser for, so the user’s action was ignored.

Fix: Add a parser with that name to the spec’s intent, or correct the name in the view (data-intent=${i.Name} catches typos at compile time).

G0012

<{tag}> intent parser for "{intent}" failed

Arguments: tag, intent.

An asynchronous intent parser rejected. The error is logged with this message, and the event produced no message.

Fix: Handle failures inside the parser (return a message that describes the failure, or undefined), or move the fallible work into a command with onFailure.

G0013

<{tag}> focus("{selector}") matched no focusable element.

Arguments: tag, selector.

A focus(selector) command found no element to focus in the component’s root after the render, so focus stayed where it was. Keyboard and screen reader users notice.

Fix: Make the selector match an element inside the component (its shadow root, or its children for shadow: false). Give targets that aren’t focusable, such as headings, tabindex="-1".

G0014

<{tag}> is on the page, but no custom element named "{tag}" is defined {seconds} s after it loaded, so it renders nothing. If it is one of your components, import the module that calls define()('{tag}', …) from the entry; for a third-party element, load its package. Ignore this for an element defined later on purpose.

Arguments: tag, seconds.

Development builds look for custom-element tags on the page that nothing has defined, 3 seconds after load and again after each later define(). Such an element renders nothing: usually the entry never imports the module that defines it.

Fix: Import the component’s module from the entry (or from a module the entry imports). For a third-party element, load its package; ignore the warning for an element you define later on purpose.

Props

G0020

<{tag}> prop "{prop}" has an asynchronous schema; it must be synchronous.

Arguments: tag, prop.

A prop’s Standard Schema returned a promise. Props are validated synchronously, while the element updates and renders, so they can’t wait for it.

Fix: Use a synchronous schema or a type guard for the prop, and do asynchronous checks in a command.

G0021

<{tag}> prop "{prop}" got an invalid value from {source}, so it is treated as missing: {issues}

Arguments: tag, prop, source, issues.

A prop value failed its type or its schema, so it is treated as missing and its default applies. Attributes are checked in every build; property sets and hydration seeds in development only.

Fix: Pass a value that matches the prop’s declaration (a numeric string for prop.number, valid JSON for prop.json), or loosen the schema.

G0022

<{tag}> is missing required prop(s): {props}.

Arguments: tag, props.

A component rendered for the first time while props declared required were still missing. The parent probably forgot an attribute or a property.

Fix: Set the prop on the element (an attribute, or .prop=${…}) before it renders, or give it a default instead of required.

G0023

<{tag}> declares prop(s) that shadow built-in element properties: {props}. Setting them changes platform behaviour (a prop named "hidden" hides the element). Rename them.

Arguments: tag, props.

A component declares props named after built-in element properties (hidden, title, id). The prop would replace the platform’s property, so setting it would change how the element behaves. Development throws; production warns.

Fix: Rename the props.

Scheduling

G0030

gyral: a deferred callback failed

Arguments: none.

A callback Gyral deferred to a microtask threw: delivering a child component’s output to its parent. The parent may not have received the output.

Fix: Look at the error logged with this message, and make sure the parent’s child() mapper and any gyral-output listener don’t throw.

G0031

<{tag}> view failed; it shows its error view, or its previous DOM stays.

Arguments: tag.

A component’s view threw during a render. Gyral reports a GyralError (phase view) through its error channel and keeps rendering the other components. The component renders its error view if its spec has one; otherwise its DOM shows its previous state.

Fix: Fix the exception in the view, using the cause of the reported error. It is often a field read on state that has a different shape than the view expects. Give the spec an error(failure, state) view so users see a fallback (Error handling).

G0032

gyral: post-render work failed

Arguments: none.

Work that runs after a render failed: a focus command, custom states from states, the Hydrated message, or the commands init returned for a resumed component.

Fix: Fix the exception logged with this message, typically in the spec’s states function or the Hydrated reducer.

G0033

gyral: rendering did not settle in one flush (a cycle between {tags}). Components are probably feeding each other props or messages; break the cycle with a condition in update.

Arguments: tags.

Rendering didn’t settle in one flush: the named components kept re-rendering each other. Components are probably feeding each other props or messages in a cycle. Development throws; production logs it and drops the rest of the work so the page doesn’t freeze.

Fix: Break the cycle with a condition in update, for example by sending a message or changing state only when the value actually differs.

G0034

settled(): the page did not settle after {rounds} flushes or busy turns. A stream is emitting without pause, or components (or drivers) are feeding each other messages in a cycle.

Arguments: rounds.

settled() rejected because messages kept arriving: more than the given number of flushes or busy turns went by without a quiet moment. Something is sending messages in a cycle, or a stream emits on every turn.

Fix: Find the cycle and break it with a condition in update, or substitute the chatty driver in the test.

Commands

G0040

{owner}: the onSuccess or onFailure mapper for driver "{driver}" threw; no message was sent.

Arguments: owner, driver.

A command’s onSuccess or onFailure mapper threw while turning a driver’s result into a message, so the result never reached update. It is reported as a GyralError (phase command), and the component’s Errored reducer, if any, receives it.

Fix: Make the mapper total: return a message, or undefined, for every input.

G0041

{owner}: driver "{driver}" failed and the command has no onFailure.

Arguments: owner, driver.

A driver failed, after any retry() policy, and the command has no onFailure. This is an error, not a warning: it is reported as a GyralError (phase command) and reaches the component’s Errored reducer, if any. Without one, the component can’t react: a spinner may spin forever.

Fix: Give the command an onFailure that turns the error into a message, and handle that message in update. Expected failures (the network, a 5xx, a refusal) should always be messages.

G0042

gyral: subscription "{name}" failed to unsubscribe

Arguments: name.

The function (or unsubscribe()) a subscription() returned threw when Gyral released the source, so the source may still be sending values or holding listeners.

Fix: Make the stop function that subscribe returns safe to call once, and return a function or an object with unsubscribe().

G0043

{owner}: no driver provides "{driver}". It is a driver token: provide an implementation by name with provideDrivers(root, { {driver}: … }) or el.drivers.

Arguments: owner, driver.

The command’s driver is a token: defineDriver<I, O, E>(name) without an implementation of its own. Nothing above the component provides that name, so the command can’t run. It is reported through the error channel (phase command); onFailure isn’t called, because there was no driver to fail.

Fix: Provide the driver where the app starts, provideDrivers(document.body, { name: implementation }), or on the element with el.drivers. In tests, pass a fake by the same name (Drivers the app provides).

Stores

G0050

<{tag}> uses store "{store}" without declaring it. Add it to the spec: stores: [{store}], so the component subscribes to its changes.

Arguments: tag, store.

A component read a store with ctx.read(store), or sent to one, without listing it in its spec. A component subscribes only to the stores it declares, so it would miss the store’s changes.

Fix: Declare the store in the spec, for example stores: [cart].

G0051

store "{store}": the server's seed failed its schema, so it starts from init. Issues: {issues}

Arguments: store, issues.

The store state the server seeded into the page failed the store’s schema, so the browser discarded it and the store starts from init. The page may show different data than the server rendered.

Fix: Fix the state the server sends, or align the store’s schema with it.

G0052

unreadable {attribute} seed on {where}

Arguments: attribute, where.

The store seed on the page, or on a <gyral-stores> provider, isn’t valid JSON, so every store in it starts from init.

Fix: Let @gyral/ssr write the seed (renderPage({ stores }), or the provider’s .instances) instead of writing it by hand, and check that nothing rewrites or truncates the HTML on its way.

G0053

<{tag}> reads store "{store}" during a server render without a store scope. Pass the request's store instances to renderPage({ stores }) or renderToString(value, { stores }).

Arguments: tag, store.

A component read a store during a server render without a store scope. On the server each request needs its own store instances, and without a scope Gyral can’t tell whose state to read.

Fix: Render through @gyral/ssr and pass the request’s instances: renderPage({ stores }) or renderToString(value, { stores }).

G0054

store "{store}" sends to "{target}" but is not held by a store scope (a registry, <gyral-stores> or the page default), so the message is dropped.

Arguments: store, target.

A store’s update sent a message to another store, but this store instance isn’t held by a store scope, so the message has nowhere to go and is dropped.

Fix: Let a scope hold the instance: the page’s default, a <gyral-stores> provider (.instances=${[…]}), or a store registry in tests.

G0055

store "{store}" has no update for message "{message}".

Arguments: store, message.

A store received a message whose _tag has no reducer in its update, so the message was dropped and the change you expected didn’t happen.

Fix: Add a reducer for the message to the store’s update, or correct the tag being sent.

Hydration

G0060

<{tag}> has an unreadable {attribute}

Arguments: tag, attribute.

A server-rendered component’s data-gyral-seed isn’t valid JSON, so the browser can’t resume the server’s state: the component starts from init, and its first render may not match the server’s HTML.

Fix: Don’t edit or write data-gyral-seed yourself. Look for whatever changes the server’s HTML on its way: a proxy, an HTML minifier, string templating.

G0061

gyral: hydration code failed to load; rendering fresh

Arguments: none.

The hydration code, which loads lazily with the first server-rendered component, failed to load, so server-rendered components render fresh instead of hydrating. The page works, but redoes the server’s work. It is usually a stale deploy: a cached page that points at a chunk that no longer exists.

Fix: Keep the previous build’s assets online for a while after a deploy, or don’t cache HTML that points at removed chunks. The network error is logged with this message.

G0062

gyral: hydration mismatch in {host} at {path}: expected {expected}, found {found}. The server's HTML differs from the first client render: a view that isn't deterministic (Date.now(), locale), a third party that changed the DOM before scripts ran, or a stale cached page (https://gyral.dev/docs/server-rendering/#mismatches).

Arguments: host, path, expected, found.

The server’s HTML differs from the first client render, so the component can’t be hydrated in place. Development throws HydrationMismatch, naming the template’s file and line; production keeps the sentence (the component, the DOM path, what was expected and found), ends it with this code, and renders the component fresh (G0063).

Fix: Make the view render the same on both sides: no Date.now(), random numbers or locale-dependent formatting in view (put them in state through a command). Also rule out a browser extension or script that changed the DOM before hydration, and a stale cached page.

G0063

<{tag}> was rendered fresh after a hydration mismatch:

Arguments: tag.

Production only: after a hydration mismatch (G0062, which follows in the same warning), Gyral cleared this component and rendered it fresh. The rest of the page stays hydrated, but this component flashes and redoes the server’s work.

Fix: Fix the mismatch the warning describes; reproducing it in development gives the full message and the template’s location.

Templates

G0070

gyral: an html template was not compiled: `{start}`. Under the gyral-compiled condition every html`…` must be compiled by the Gyral Vite preset.

Arguments: start.

A bundle built with the Vite preset leaves out the runtime template preparer, so every html template must be precompiled, and this one wasn’t. The build normally fails before this can happen.

Fix: Import html (and svg) from @gyral/core, or from a package listed in the compiler’s sources, and use it directly as a tag: the compiler can’t follow an alias, a call or a re-export.

G0071

gyral: template rule 11: a page shell rendered in the browser.

Arguments: none.

A page shell, a template with <!doctype>, <html>, <head> or <body>, was rendered in the browser. Only the server renders document-level tags. Development reports it as template rule 11, with the full explanation.

Fix: Render the page shell on the server with @gyral/ssr’s renderPage, and render only components in the browser.

G0072

gyral: this page's Trusted Types policy list does not allow the policy "gyral", so templates are parsed from plain strings, which works only while Trusted Types are not enforced. Add `trusted-types gyral` to the Content-Security-Policy.

Arguments: none.

Gyral parses template HTML and raw() markup through a Trusted Types policy named gyral. The page’s Content-Security-Policy has a trusted-types directive that lists allowed policy names without gyral, so the browser refused to create it. Gyral falls back to plain strings, which works only while the page doesn’t enforce Trusted Types (require-trusted-types-for 'script'). Development warns once.

Fix: Add gyral to the policy list: trusted-types gyral (with your own policies, if any). If you don’t use Trusted Types, remove the trusted-types directive.

Error handling

G0073

<{tag}> update for "{message}" failed; the state is unchanged.

Arguments: tag, message.

A reducer threw while handling the named message. Nothing changed: the state stays as it was and the commands that reducer would have returned don’t run. It is reported as a GyralError (phase update), and the component’s Errored reducer, if any, receives it.

Fix: Fix the exception in that reducer, using the cause of the reported error. Add an Errored reducer if the component should show an error state (Error handling).

G0074

<{tag}> init failed; it shows its error view, or stays empty.

Arguments: tag.

A component’s init threw, so it has no state. It renders its error(failure, undefined) view if its spec has one, or stays empty. The error is reported as a GyralError (phase init).

Fix: Fix the exception in init, using the cause of the reported error; often a prop or seed read with an unexpected shape. Give the spec an error view for a visible fallback.

G0075

<{tag}> element hook failed; the other hooks still ran.

Arguments: tag.

An element hook’s client function threw. Gyral reported it (phase hook) and still ran the other hooks of that render; the element itself is in the DOM.

Fix: Fix the exception in the hook, using the cause of the reported error.

G0076

store "{store}": update for "{message}" failed; the state is unchanged.

Arguments: store, message.

A store’s reducer threw while handling the named message. The store’s state is unchanged and its commands don’t run. The error is reported as a GyralError (phase store); the sender isn’t affected.

Fix: Fix the exception in that store reducer, using the cause of the reported error.

G0077

store "{store}": a subscriber failed; the other subscribers were still notified.

Arguments: store.

A component that reads the store threw while handling StoreChanged. The other subscribers were still notified and the store’s commands still ran.

Fix: Fix the exception in that component’s StoreChanged reducer (or the code it calls), using the cause of the reported error.

G0078

<{tag}> failed to render on the server; it renders its error view (or nothing) and starts fresh in the browser.

Arguments: tag.

A component’s init or view threw during server rendering. It rendered its error view (or nothing), marked data-gyral-error and without a seed, and the rest of the page was sent; the browser starts that component fresh. renderPage’s onError received the error.

Fix: Fix the exception, using the error your onError received. Pass onError: 'throw' to renderPage if a failing component should fail the whole page instead, so the route can answer with its error page.

Subscriptions

G0079

<{tag}> subscriptions returned two commands for lane "{lane}"; only the first runs. Give each its own `key`.

Arguments: tag, lane.

The component’s subscriptions returned two commands in the same lane: the same key, or no key and the same driver. Gyral keeps one running command per lane, so only the first runs. Development warns.

Fix: Give each subscription its own key, such as one per room or per URL.

G0080

<{tag}> subscriptions kept restarting: a subscription's input data changes with every message it sends (for example a timestamp or a counter in the input). Keep inputs to what should restart it; functions are ignored, so to restart on a new selector, change the key.

Arguments: tag.

A subscription restarted again and again: its input changed with every message it sent, so each new state asked for a different input, which restarted it. Gyral stops after 100 rounds rather than loop.

Fix: Keep a subscription’s input to what should restart it (an id, a URL), not values that its own messages change, such as a counter or a timestamp.

Element calls

G0085

<{tag}> call("{selector}", "{method}") failed

Arguments: tag, selector, method.

A call(selector, method, …args) command failed after the render: no element of the component matched the selector, the element has no such method, or the method threw or rejected. The reported error’s cause says which. It is reported through the error channel (phase command).

Fix: Check that the element is rendered when the command runs (return the command from the reducer whose new state renders it), that the selector matches inside the component’s own tree, and that the method exists on that element.

G0086

call("{selector}", "{method}"): arguments must be plain data.

Arguments: selector, method.

Development checks that a call() command’s arguments are plain data that can be cloned (strings, numbers, arrays and plain objects). A function, an element or a class instance would make the command impossible to compare or record in a test.

Fix: Pass plain data, and let the element look up anything else itself.