eythaann/Seelen-UI · error · Error

Widget definition not found for ${currentWidgetId}

Error message

Widget definition not found for ${currentWidgetId}

What it means

During vanilla widget bootstrap (`MainSetup.ts`), the app fetches the widget list from the backend (`state_get_widgets`) and looks up the definition matching this webview's widget id. If none matches, `window.__SLU_WIDGET` stays undefined and the setup throws `Widget definition not found for <id>`. This means the backend does not know a widget with that id.

Source

Thrown at src/ui/vanilla/entry-point/MainSetup.ts:15

import type { Widget } from "@seelen-ui/lib/types";
import { _invoke, webviewInfo } from "src/ui/vanilla/entry-point/_tauri.ts";
import { listen } from "@tauri-apps/api/event";

import { hookLocalStorage } from "src/ui/vanilla/entry-point/_LocalStorage";

const indexJsCode = fetch("./index.js").then((res) => res.text());

// initialize global widget variable, needed by slu-lib
const currentWidgetId = webviewInfo.widgetId;
const widgetList = await _invoke<Widget[]>("state_get_widgets");
window.__SLU_WIDGET = widgetList.find((widget) => widget.id === currentWidgetId)!;

if (!window.__SLU_WIDGET) {
  throw new Error(`Widget definition not found for ${currentWidgetId}`);
}

// reload if widget definition changed
listen<Widget[]>("widgets-changed", ({ payload }) => {
  const actual = payload.find((widget) => widget.id === currentWidgetId);
  if (actual && JSON.stringify(actual) !== JSON.stringify(window.__SLU_WIDGET)) {
    window.location.reload();
  }
});

// set document id
document.documentElement.id = currentWidgetId;

// hook local storage, to avoid collition of keys
hookLocalStorage(currentWidgetId);

// add base css
const link = document.createElement("link");

View on GitHub (pinned to dee4aaa940)

Solutions

  1. Verify the widget id in the webview URL matches the `id` in the widget's `metadata.yml` exactly.
  2. Restart Seelen UI (or re-run `slu resource load widget ./my-widget`) so the backend registry includes the widget.
  3. Check that `state_get_widgets` returns the expected list (log it) and that the widget resource loaded without errors.

Example fix

// before
window.__SLU_WIDGET = widgetList.find((w) => w.id === currentWidgetId)!;
// after
window.__SLU_WIDGET = widgetList.find((w) => w.id === currentWidgetId);
if (!window.__SLU_WIDGET) {
  console.error("Available:", widgetList.map((w) => w.id));
  throw new Error(`Widget definition not found for ${currentWidgetId}`);
}
Defensive patterns

Strategy: validation

Validate before calling

const widgetList = await _invoke<Widget[]>("state_get_widgets");
const def = widgetList.find((w) => w.id === currentWidgetId);
if (!def) {
  console.error("Registered ids:", widgetList.map((w) => w.id));
  // bail out gracefully before assigning window.__SLU_WIDGET
}

Type guard

function isRegisteredWidget(widgets: Widget[], id: string): boolean {
  return widgets.some((w) => w.id === id);
}

Try / catch

try {
  await bootstrapWidget();
} catch (e) {
  if (String((e as Error).message).startsWith("Widget definition not found")) {
    console.error("Widget id mismatch — check metadata.yml id vs webview id");
  } else throw e;
}

Prevention

When it happens

Trigger: The widget id encoded in the webview URL is not present in the backend's widget registry — e.g. widget was uninstalled/renamed while its webview still runs, a custom widget id mismatch between `metadata.yml` and the launching code, or `state_get_widgets` returned a stale/partial list.

Common situations: Developing a custom widget with an id that doesn't match the registered resource id (`@user/name`); updating a built-in widget's id without restarting the app; loading a widget resource whose metadata failed to parse on the backend.

Related errors


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