koala73/worldmonitor · error · Error

Search modal is not initialised

Error message

Search modal is not initialised

What it means

App's search-open path reads this.state.searchModal; if it is still null (search modal never initialized during boot, or torn down), it throws 'Search modal is not initialised'. This is an internal lifecycle guard ensuring modal.open() is only called on a live modal instance.

Solutions

  1. Wait for app boot/init completion before invoking search programmatically
  2. Check app state for searchModal availability before opening
  3. Ensure the search modal initializer runs before registering the search hotkey
  4. If caused by a teardown race, guard re-open calls against the destroyed modal instance

Example fix

// before
app.openSearch({ initialQuery: q }); // throws if modal not ready
// after
if (!app.isSearchModalInitialized()) return;
app.openSearch({ initialQuery: q });
Defensive patterns

Strategy: try-catch

Validate before calling

if (!app || typeof app.isSearchModalInitialized !== 'function' || !app.isSearchModalInitialized()) {
  return; // defer search until boot completes
}

Type guard

function canOpenSearch(app) {
  return app != null && app.state?.searchModal != null;
}

Try / catch

try {
  app.openSearch({ initialQuery: q });
} catch (e) {
  if (e.message === 'Search modal is not initialised') {
    // queue the search until app:ready, or retry after init
  } else throw e;
}

Prevention

When it happens

Trigger: Triggering search (keyboard shortcut or programmatic openSearch) before the app finishes initializing the search modal, or after the modal was destroyed; toggling search during boot or teardown races.

Common situations: User hits the search hotkey very early during page load; automated tests/e2e driving search before init completes; rapid destroy/re-init cycles (e.g. view switches) leaving state.searchModal null.

Related errors


AI-assisted analysis of koala73/worldmonitor@e586b8b4b8 (2026-09-01). Data as JSON: /api/errors/c0773dda54b53efd. Report an issue: GitHub.

Appendix: source

Thrown at src/App.ts:1860

      // palette's query/debounce state or unrelated human actions.
      this.searchManager?.cancelPendingProgrammaticSelection();
      if (pendingGate && !pendingGate.isCurrent()) return false;

      const existingModal = this.state.searchModal;
      if (options.toggle && existingModal?.isOpen()) {
        existingModal.close();
        return false;
      }

      const togglingBeforeLoad = Boolean(options.toggle) && !this.searchManager;
      if (togglingBeforeLoad) {
        this.searchToggleDesiredOpen = !this.searchToggleDesiredOpen;
      }

      epoch = ++this.openSearchEpoch;
      const manager = await raceWebMcpAbort(this.ensureSearchManager(), options.signal);
      throwIfWebMcpAborted(options.signal);
      if (this.openSearchEpoch !== epoch) return false;
      if (pendingGate && !pendingGate.isCurrent()) return false;

      const wantOpen = togglingBeforeLoad ? this.searchToggleDesiredOpen : true;
      if (!wantOpen) return false;

      manager.updateSearchIndex();
      const modal = this.state.searchModal;
      if (!modal) throw new Error('Search modal is not initialised');
      throwIfWebMcpAborted(options.signal);
      modal.open(pendingGate ? pendingId : options.replaceOverlayId);
      if (options.initialQuery) modal.applyQuery(options.initialQuery);
      return modal.isOpen();
    } catch (error) {
      const actionWasCancelled = pendingGate !== null && !pendingGate.isCurrent();
      const invocationWasCancelled = options.signal?.aborted === true;
      if (!this.state.isDestroyed && !actionWasCancelled && !invocationWasCancelled) {
        console.warn('[search] Failed to load search manager:', error);
        if (!options.throwOnFailure) showToast('Search failed to load. Please try again.');

View on GitHub (pinned to e586b8b4b8)