{"record":{"id":"14eeb7bb3f02b2f8","repo":"eythaann/Seelen-UI","slug":"lazysignal-was-not-initialized","errorCode":null,"errorMessage":"LazySignal was not initialized","messagePattern":"LazySignal was not initialized","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"libs/ui/react/utils/LazySignal.ts","lineNumber":17,"sourceCode":"import { Signal } from \"@preact/signals\";\n\n/**\n * Structure done to work with async event programming\n */\nexport class LazySignal<T> extends Signal<T> {\n  private initialized = false;\n  private intializing: Promise<Signal<T>> | null = null;\n\n  constructor(private initializer: () => Promise<T>) {\n    super();\n    this.setByPayload = this.setByPayload.bind(this);\n  }\n\n  get value(): T {\n    if (!this.initialized) {\n      throw new Error(\"LazySignal was not initialized\");\n    }\n    return super.value;\n  }\n\n  set value(value: T) {\n    this.initialized = true;\n    super.value = value;\n  }\n\n  /**\n   * Will call the initializer and set the value if not already set\n   * via another setters.\n   */\n  public init(): Promise<Signal<T>> {\n    if (!this.intializing) {\n      this.intializing = this.initializer().then((initial) => {\n        if (!this.initialized) {\n          this.value = initial;","sourceCodeStart":1,"sourceCodeEnd":35,"githubUrl":"https://github.com/eythaann/Seelen-UI/blob/dee4aaa94066c5d0888ab25554864862fc47be15/libs/ui/react/utils/LazySignal.ts#L1-L35","documentation":"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).","triggerScenarios":"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().","commonSituations":"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.","solutions":["Always await $signal.init() once during app bootstrap before rendering consumers.","Gate the UI on an initialized flag / Suspense so value is only read after init resolves.","Ensure init is awaited, not fire-and-forget.","Provide a safe accessor: signal.initialized ? signal.value : defaultValue."],"exampleFix":"// before: const $data = lazySignal(fetchData); console.log($data.value); // throws\n// after: const $data = lazySignal(fetchData); await $data.init(); console.log($data.value); // ok","handlingStrategy":"validation","validationCode":"if (!$data.initialized) { await $data.init(); } const v = $data.value;","typeGuard":"function isReady<T>(s: LazySignal<T> & { initialized: boolean }): boolean { return s.initialized; }","tryCatchPattern":"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; } }","preventionTips":["Call await signal.init() once during app bootstrap, before first render.","Register event subscribers before init(), per the documented pattern.","Never read .value at module import time.","Expose signals through getters that check initialized and provide a fallback."],"tags":["initialization","async","react","state"],"backgroundTag":"signal-read-before-init","analyzedSha":"dee4aaa94066c5d0888ab25554864862fc47be15","analyzedAt":"2026-09-03T10:20:37.842Z","contentChangedAt":"2026-09-03T10:20:37.842Z","schemaVersion":2},"datasetVersion":"2026-09-10T17:17:09.494Z"}