eythaann/Seelen-UI · error · Error

The library is being used on a non Seelen UI environment

Error message

The library is being used on a non Seelen UI environment

What it means

Widget.getCurrent() is the static accessor for the widget instance running inside a Seelen UI webview. The library reads the global __SLU_WIDGET injection that Seelen UI sets on every widget webview before running its code; if that global is missing, the code is not running inside a Seelen UI widget environment, so the library refuses to continue rather than returning a broken Widget instance.

Source

Thrown at libs/core/src/state/widget/mod.ts:44

interface WidgetInternalState {
  hwnd: number;
  initialized: boolean;
  ready: boolean;
  firstFocus: boolean;
}

/**
 * Represents the widget instance running in the current webview
 */
export class Widget {
  /**
   * Alternative accesor for the current running widget.\
   * Will throw if the library is being used on a non Seelen UI environment
   */
  static getCurrent(): Widget {
    const scope = globalThis as ExtendedGlobalThis;
    if (!scope.__SLU_WIDGET) {
      throw new Error("The library is being used on a non Seelen UI environment");
    }
    return (
      scope.__SLU_WIDGET_INSTANCE || (scope.__SLU_WIDGET_INSTANCE = new Widget(scope.__SLU_WIDGET))
    );
  }

  /** The current running widget */
  static get self(): Widget {
    return Widget.getCurrent();
  }

  /** widget id */
  public readonly id: WidgetId;
  /** widget definition */
  public readonly def: IWidget;
  /** decoded widget instance information */
  public readonly decoded: WidgetInformation;
  /** current webview where the widget is running */

View on GitHub (pinned to dee4aaa940)

Solutions

  1. Run the code inside a Seelen UI webview (load the widget through Seelen UI, not a plain browser).
  2. For tests or standalone dev, stub the environment before importing the library: set (globalThis as any).__SLU_WIDGET = { id: 'test', ... } or mock @seelen-ui/lib.
  3. Guard the call site: check (globalThis as any).__SLU_WIDGET before calling getCurrent() and take a no-op path outside Seelen UI.
  4. If inside Seelen UI and still failing, update @seelen-ui/lib and Seelen UI to matching versions so the injection global matches.

Example fix

// before: const widget = Widget.getCurrent(); // throws in plain browser/tests
// after: if (!(globalThis as any).__SLU_WIDGET) { return null; } const widget = Widget.getCurrent();
Defensive patterns

Strategy: validation

Validate before calling

function isSeelenUiEnv(): boolean { return Boolean((globalThis as any).__SLU_WIDGET); } // call before getCurrent(); if false, skip widget setup or inject a test stub

Type guard

function isInSeelenUi(): boolean { return typeof (globalThis as any).__SLU_WIDGET !== 'undefined' && (globalThis as any).__SLU_WIDGET !== null; }

Try / catch

let widget: Widget | null = null; try { widget = Widget.getCurrent(); } catch (e) { if (e instanceof Error && e.message.includes('non Seelen UI environment')) { widget = null; } else { throw e; } }

Prevention

When it happens

Trigger: Calling Widget.getCurrent() (directly or via the Widget.ready() flow) in a plain browser tab, a normal webview not spawned by Seelen UI, a unit-test environment (jsdom/node) without the global injected, or a webview whose preload/injection script failed to define globalThis.__SLU_WIDGET before library code ran.

Common situations: Running widget frontend code standalone with a dev server; executing widget modules in Vitest/Jest tests; loading @seelen-ui/lib from a random website; opening the widget's dist/index.html directly in a browser; injection-order regression where module top-level code calls getCurrent() before the global is injected.

Related errors


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