eythaann/Seelen-UI · error · Error
Widget was not initialized before ready
Error message
Widget was not initialized before ready
What it means
Widget.ready() signals that a widget finished setup and can be shown (unless lazy, where it is shown on a trigger action). The library requires the lifecycle to start with initialization (which computes the decoded webview label and config); calling ready() on an instance whose runtimeState.initialized flag is false means ready() was called out of order, so it throws instead of proceeding with an unconfigured widget.
Solutions
- Await init before ready(): await Widget.getCurrent().init(...) then await widget.ready().
- Use the singleton from Widget.getCurrent() rather than constructing Widget manually.
- Gate ready() on a flag or a promise that resolves after initialization.
- Log runtimeState before ready() when debugging order issues.
Example fix
// before: const widget = Widget.getCurrent(); widget.ready(); // throws // after: const widget = Widget.getCurrent(); await widget.init(); await widget.ready();
Defensive patterns
Strategy: validation
Validate before calling
// track init completion in your bootstrap: let initialized = false; await widget.init(); initialized = true; if (!initialized) throw new Error('call init() before ready()'); Type guard
function isInitialized(w: Widget): boolean { return (w as unknown as { runtimeState: { initialized: boolean } }).runtimeState.initialized; } Try / catch
try { await widget.ready(); } catch (e) { if (e instanceof Error && e.message.startsWith('Widget was not initialized')) { await widget.init(); await widget.ready(); } else { throw e; } } Prevention
- Always await init() before ready() in the widget entry point.
- Use the Widget.getCurrent() singleton instead of constructing Widget manually.
- Never call ready() from top-level code that may run before init.
- Keep init/ready ordering in one bootstrap function to make the lifecycle auditable.
When it happens
Trigger: Calling widget.ready() before the widget's init step completed; forgetting `await` on init and calling ready() synchronously; creating a second Widget instance manually (bypassing the initialized getCurrent() singleton) and calling ready() on it; calling ready() from module top-level code that races the async init.
Common situations: Restructuring widget entry code and accidentally moving ready() above init; dropping an await during a refactor; using new Widget(...) directly; init triggered by an event that has not fired yet.
Related errors
- LazyRune was not initialized
- LazySignal was not initialized
- Monitor settings not initialized
- no translation for key
- The library is being used on a non Seelen UI environment
AI-assisted analysis of eythaann/Seelen-UI@dee4aaa940 (2026-09-03).
Data as JSON: /api/errors/c0055a5271998031.
Report an issue: GitHub.
Appendix: source
Thrown at libs/core/src/state/widget/mod.ts:294
if (options.disableCssAnimations ?? true) {
await disableAnimationsOnPerformanceMode();
} else {
console.trace("Animations won't be disabled because widget configuration");
}
}
/**
* Will mark the widget as `ready` and pool pending triggers.
*
* If the widget is not lazy this will inmediately show the widget.
* Lazy widget should be shown on trigger action.
*/
public async ready(options: ReadyWidgetOptions = {}): Promise<void> {
const { show = !this.def.lazy } = options;
if (!this.runtimeState.initialized) {
throw new Error(`Widget was not initialized before ready`);
}
if (this.runtimeState.ready) {
console.warn(`Widget is already ready`);
return;
}
this.runtimeState.ready = true;
await this.autoSizer?.execute();
if (show && !(await this.window.isVisible())) {
await this.show();
}
// this will mark the widget as ready, and send pending trigger event if exists
await invoke(SeelenCommand.SetCurrentWidgetStatus, { status: WidgetStatus.Ready });
}
View on GitHub (pinned to dee4aaa940)