eythaann/Seelen-UI · error · Error

LazySignal was not initialized

Error message

LazySignal was not initialized

What it means

LazySignal defers initialization until .init() runs its async initializer; reading .value before initialization would silently return an empty value. To make misuse loud, the value getter throws unless the signal has been initialized (a value set — including via the setter — marks it initialized).

Source

Thrown at libs/ui/react/utils/LazySignal.ts:17

import { Signal } from "@preact/signals";

/**
 * Structure done to work with async event programming
 */
export class LazySignal<T> extends Signal<T> {
  private initialized = false;
  private intializing: Promise<Signal<T>> | null = null;

  constructor(private initializer: () => Promise<T>) {
    super();
    this.setByPayload = this.setByPayload.bind(this);
  }

  get value(): T {
    if (!this.initialized) {
      throw new Error("LazySignal was not initialized");
    }
    return super.value;
  }

  set value(value: T) {
    this.initialized = true;
    super.value = value;
  }

  /**
   * Will call the initializer and set the value if not already set
   * via another setters.
   */
  public init(): Promise<Signal<T>> {
    if (!this.intializing) {
      this.intializing = this.initializer().then((initial) => {
        if (!this.initialized) {
          this.value = initial;

View on GitHub (pinned to dee4aaa940)

Solutions

  1. Always await $signal.init() once during app bootstrap before rendering consumers.
  2. Gate the UI on an initialized flag / Suspense so value is only read after init resolves.
  3. Ensure init is awaited, not fire-and-forget.
  4. Provide a safe accessor: signal.initialized ? signal.value : defaultValue.

Example fix

// before: const $data = lazySignal(fetchData); console.log($data.value); // throws
// after: const $data = lazySignal(fetchData); await $data.init(); console.log($data.value); // ok
Defensive patterns

Strategy: validation

Validate before calling

if (!$data.initialized) { await $data.init(); } const v = $data.value;

Type guard

function isReady<T>(s: LazySignal<T> & { initialized: boolean }): boolean { return s.initialized; }

Try / catch

try { use($data.value); } catch (e) { if (e instanceof Error && e.message === 'LazySignal was not initialized') { await $data.init(); use($data.value); } else { throw e; } }

Prevention

When it happens

Trigger: Reading $signal.value before calling await $signal.init(); calling init() without awaiting it and reading value synchronously afterwards; a React component rendering before an effect kicked off init; consuming a shared signal from another module where nobody called init().

Common situations: Reading the signal during first render before init resolves; top-level module code reading the value at import time; refactors removing the init() call; a second component assuming someone else initialized the signal.

Related errors


AI-assisted analysis of eythaann/Seelen-UI@dee4aaa940 (2026-09-03). Data as JSON: /api/errors/14eeb7bb3f02b2f8. Report an issue: GitHub.