The unhappy path is in the type
Last reviewed: July 2026.
Anyone who has reviewed AI-generated UI knows the signature defect: the happy path is polished and the rest doesn't exist. The loading state is an unstyled flicker. The empty state is a blank pane. The error state is an uncaught exception. Not because the model is careless, exactly – because nothing required otherwise. In every mainstream UI language, loading/empty/error handling is a convention the author "should" follow, and conventions are precisely what a stochastic author follows stochastically.
Fuaran moves the convention into the type system. Every node carries state-behaviour
slots – onLoading, onEmpty, onError – and the validator requires them wherever
they are reachable: any node whose data binding can be loading, empty or failed must declare what renders in that case, or the build fails, naming the node and the missing
slot. The slots are declarative alternate views, not imperative branches (the renderer selects between them), which is also what lets a server render pick the right one for
first paint (a resolved value renders the value; an unresolved binding renders the
declared loading state, never a blank).
Two things make this more than a lint rule:
- The requirement is derived, not blanket. The language knows, from the binding's registration, which states are actually reachable – a static literal can't be "loading", a query can. The demand is exactly as wide as the risk.
- It binds the AI author identically. A model cannot emit a Fuaran tree that skips the unhappy paths and have it decode; the omission comes back as a typed refusal like any other shape error (see Errors that enumerate the fix). The reviewer no longer has to notice the missing empty state – the gate did.
The general principle is the quiet thesis of the whole language: disciplines that previously lived in human convention can be typed. "Remember to handle loading" is a code-review comment; a required slot is a contract. The first depends on who is reviewing; the second doesn't depend on anyone.
It also changes what "done" means for a generated UI. A happy-path-only emission is not a rough draft that needs finishing – it is an invalid artefact that never rendered. That is a better default for interfaces that real users will meet on slow connections, with empty accounts, and against APIs that sometimes fail – which is to say, all of them.