eythaann/Seelen-UI · error · Error
Missing widget id on webview label
Error message
Missing widget id on webview label
What it means
Seelen UI encodes each widget webview's identity as a base64url label of the form '<widgetId>?<query>'. getDecodedWebviewLabel() decodes the current webview's label and splits it; if the decoded label has no part before the '?', there is no widget id, meaning the label was not produced by the widget spawn machinery, so the library cannot determine which widget is running.
Source
Thrown at libs/core/src/state/widget/mod.ts:419
type ExtendedGlobalThis = typeof globalThis & {
__SLU_WIDGET?: IWidget;
__SLU_WIDGET_INSTANCE?: Widget;
};
export const SeelenSettingsWidgetId: WidgetId = "@seelen/settings" as WidgetId;
export const SeelenPopupWidgetId: WidgetId = "@seelen/dialog" as WidgetId;
export const SeelenWegWidgetId: WidgetId = "@seelen/weg" as WidgetId;
export const SeelenToolbarWidgetId: WidgetId = "@seelen/fancy-toolbar" as WidgetId;
export const SeelenWindowManagerWidgetId: WidgetId = "@seelen/window-manager" as WidgetId;
export const SeelenWallWidgetId: WidgetId = "@seelen/wallpaper-manager" as WidgetId;
function getDecodedWebviewLabel(): [WidgetId, string | undefined] {
const encondedLabel = getCurrentWebview().label;
const decodedLabel = new TextDecoder().decode(decodeBase64Url(encondedLabel));
const [id, query] = decodedLabel.split("?");
if (!id) {
throw new Error("Missing widget id on webview label");
}
return [id as WidgetId, query];
}
function getDefinitionDefaultValues(definition: WidgetConfigDefinition): Record<string, unknown> {
const config: Record<string, unknown> = {};
// Check if it's a group (has "group" property)
if ("group" in definition) {
// Recursively process all items in the group
for (const item of definition.group.items) {
Object.assign(config, getDefinitionDefaultValues(item));
}
} else {
// It's a setting item, extract key and defaultValue
const item = definition as WidgetSettingItem;
if ("key" in item && "defaultValue" in item) {
config[item.key] = item.defaultValue;View on GitHub (pinned to dee4aaa940)
Solutions
- Load the widget through Seelen UI's standard widget creation path so its label is the encoded id?query form.
- If mocking in tests, set the label to the correct base64url encoding of '<widgetId>'.
- Verify the current webview's label decodes to a non-empty widget id before use.
- Align @seelen-ui/lib and Seelen UI versions to avoid label-format mismatches.
Example fix
// before (test mock): getCurrentWebview: () => ({ label: 'main' })
// after: getCurrentWebview: () => ({ label: toBase64Url('my-widget@example') }) // decodes to a real widget id Defensive patterns
Strategy: validation
Validate before calling
const label = getCurrentWebview().label; const decoded = new TextDecoder().decode(decodeBase64Url(label)); if (!decoded.split('?')[0]) throw new Error('webview label has no widget id'); Type guard
function hasWidgetIdLabel(label: string): boolean { try { return Boolean(new TextDecoder().decode(decodeBase64Url(label)).split('?')[0]); } catch { return false; } } Try / catch
let id: WidgetId | undefined; try { [id] = getDecodedWebviewLabel(); } catch (e) { if (e instanceof Error && e.message.includes('Missing widget id')) { id = undefined; } else { throw e; } } Prevention
- Create widget webviews only through Seelen UI's widget spawn path.
- In tests, mock labels with properly base64url-encoded ids.
- Assert the decoded label shape once at startup to fail fast with context.
- Align lib and app versions to avoid label-format drift.
When it happens
Trigger: Accessing [id, query] or the query getter on a webview whose label is not a base64url-encoded 'id?query' string — a webview created manually in Tauri, a label that decodes to an empty string, or a Seelen UI/lib version mismatch where label encoding changed; tests mocking getCurrentWebview() with a plain label like 'main'.
Common situations: Running widget code in a webview registered outside the Seelen UI widget factory; hand-crafting webview labels in custom tooling; upgrading Seelen UI or the lib so the label format differs; test mocks using unencoded labels.
Related errors
AI-assisted analysis of eythaann/Seelen-UI@dee4aaa940 (2026-09-03).
Data as JSON: /api/errors/d2a813b5afb0a89d.
Report an issue: GitHub.