eythaann/Seelen-UI · warning

Context menu has no target to emit to

Error message

Context menu has no target to emit to

What it means

In the context-menu widget, MenuItem's handleClick() forwards the selected item's event to the menu's target: gState.forwardTo if set, otherwise gState.owner. When neither is set there is no webview/window to emit the selection to, so the click is ignored with this warning — the menu was opened without a proper owner/forward target.

Source

Thrown at src/ui/svelte/context-menu/MenuItem.svelte:24

  interface MenuItemProps {
    item: Extract<ContextMenuItem, { type: "Item" }>;
  }

  let { item }: MenuItemProps = $props();

  // Optimistic state for checked
  let internalChecked = $state(false);

  $effect.pre(() => {
    internalChecked = item.checked!!;
  });

  function handleClick() {
    let target = gState.forwardTo || gState.owner;

    if (!target) {
      console.warn("Context menu has no target to emit to");
      return;
    }

    if (item.disabled) {
      return;
    }

    if (item.checked !== null) {
      // Toggle optimistic state
      internalChecked = !internalChecked;
    }

    emitTo<ContextMenuCallbackPayload>(target, item.callbackEvent, {
      key: item.key,
      value: item.value,
      checked: item.checked !== null ? internalChecked : null,
      meta: gState.data?.meta,
    });

View on GitHub (pinned to dee4aaa940)

Solutions

  1. Ensure the code opening the menu passes a valid target (owner webview label or forwardTo) in the context-menu state/payload.
  2. Verify a listener exists in the target window for the menu's emitted event (e.g. subscribe to the context-menu result event) and that the target is still alive when items are clicked.
  3. Close/reopen the menu if its originating window was destroyed — stale menus have no target.
  4. In the target widget, confirm the menu state was hydrated before user interaction (wait for the state/ready event).

Example fix

// before (opener side)
showContextMenu({ items }); // no target -> "no target to emit to"

// after
showContextMenu({ items, forwardTo: currentWebviewLabel });
// or in the menu, guard and close when orphaned:
if (!gState.forwardTo && !gState.owner) {
  console.warn("Context menu has no target to emit to");
  closeMenu();
  return;
}
Defensive patterns

Strategy: validation

Validate before calling

if (!menuState.forwardTo && !menuState.owner) {
  throw new Error("Cannot open context menu without an owner or forwardTo target");
}
showContextMenu(menuState);

Type guard

function hasMenuTarget(s: { forwardTo?: string | null; owner?: string | null }):
  s is { forwardTo: string; owner?: string | null } | { forwardTo?: string | null; owner: string } {
  return Boolean(s.forwardTo || s.owner);
}

Try / catch

// in the target widget
try {
  await subscribe(ContextMenuEvent, handler);
} catch (err) {
  console.error("Menu target is not listening for selections", err);
}

Prevention

When it happens

Trigger: A context menu was shown (via the context-menu widget) without the emitting side passing an owner or forwardTo target — e.g. menu opened programmatically with incomplete state, the owner webview closed before the item was clicked, or state not hydrated when the menu is triggered from a detached/preloaded webview.

Common situations: Showing a context menu from custom widget code that omits the target in the open payload; the original window that opened the menu was destroyed while the menu stayed open; race where menu item is clicked before gState is populated; theme/plugin triggering the menu without wiring a listener for the emitted event.

Related errors


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