ILHA004: Generator resumed while an instruction was in flight
Ilha tried to drive a generator component again before the instruction it yielded finished.
A generator component yields one instruction at a time, such as an Effect or a Stream. Ilha resumes the generator when that instruction finishes. If anything drives the same component again while an instruction is pending, Ilha throws ILHA004.
Why it happens
- Two
mount()calls target the same running component fiber. - Custom renderer code calls the runtime’s generator driver twice for one fiber.
You rarely see this from ordinary components. It signals that two drivers share one fiber.
Bad
import * as Effect from "effect/Effect";
import { mount } from "ilha";
function* Status() {
yield Effect.never;
}
// A renderer that re-enters the same fiber while `Effect.never` is pending.
Fixed
Mount each generator component once per host, and let Ilha resume it:
import * as import EffectEffect from "effect/Effect";
import { const mount: (el: Element, fn: Component, opts?: MountOptions) => (() => void)mount } from "ilha";
function* function Status(): Generator<string | number | bigint | boolean | (() => View | undefined | Promise<View | undefined>) | GeneratorFn | VNode | UnsafeHtml | AtomView | Stream<View, unknown, unknown> | Iterable<View> | Effect.Effect<void, never, never> | null | undefined, void, unknown>Status() {
yield <JSX.IntrinsicElements.p: HTMLAttributes<HTMLParagraphElement>p>loading</JSX.IntrinsicElements.p: HTMLAttributes<HTMLParagraphElement>p>;
yield import EffectEffect.const sleep: (duration: Input) => Effect.Effect<void>Returns an effect that suspends the current fiber for the specified duration
without blocking a JavaScript thread.
**Example** (Pausing without blocking)
```ts import.meta.vitest
import { Effect } from "effect"
const output: Array<unknown> = []
const program = Effect.gen(function*() {
yield* Effect.sync(() => { output.push("Start") })
yield* Effect.sleep(0)
yield* Effect.sync(() => { output.push("End") })
})
await Effect.runPromise(program)
output // => ["Start", "End"]
```sleep(100);
yield <JSX.IntrinsicElements.p: HTMLAttributes<HTMLParagraphElement>p>ready</JSX.IntrinsicElements.p: HTMLAttributes<HTMLParagraphElement>p>;
}
function mount(el: Element, fn: Component, opts?: MountOptions): (() => void)mount(var document: Document**`window.document`** returns a reference to the document contained in the window.
[MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/document)document.Document.body: HTMLElementThe **`Document.body`** property represents the <body> or <frameset> node of the current document, or null if no such element exists.
[MDN Reference](https://developer.mozilla.org/docs/Web/API/Document/body)body, function Status(): Generator<string | number | bigint | boolean | (() => View | undefined | Promise<View | undefined>) | GeneratorFn | VNode | UnsafeHtml | AtomView | Stream<View, unknown, unknown> | Iterable<View> | Effect.Effect<void, never, never> | null | undefined, void, unknown>Status);