cjpais/Handy · warning

Failed to show main window for permission onboarding:

Error message

Failed to show main window for permission onboarding:

What it means

revealMainWindowForPermissions invokes the showMainWindowCommand Tauri command to bring the main window forward when permission onboarding needs attention. A rejection lands in this catch; the onboarding flow continues, but the settings/permission window may remain hidden behind other windows or minimized, so the user sees an app that started without any visible window.

Source

Thrown at src/App.tsx:180

            model:
              event.payload.model_name || t("errors.modelLoadFailedUnknown"),
          }),
          {
            description: event.payload.error,
          },
        );
      }
    });
    return () => {
      unlisten.then((fn) => fn());
    };
  }, [t]);

  const revealMainWindowForPermissions = async () => {
    try {
      await commands.showMainWindowCommand();
    } catch (e) {
      console.warn("Failed to show main window for permission onboarding:", e);
    }
  };

  const checkOnboardingStatus = async () => {
    try {
      const settingsResult = await commands.getAppSettings();
      const hasCompletedOnboarding =
        settingsResult.status === "ok" &&
        settingsResult.data.onboarding_completed === true;
      const currentPlatform = platform();

      if (hasCompletedOnboarding) {
        // Returning user - check if they need to grant permissions first
        setIsReturningUser(true);

        if (currentPlatform === "macos") {
          try {
            const [hasAccessibility, hasMicrophone] = await Promise.all([

View on GitHub (pinned to c89b7bf389)

Solutions

  1. Confirm the label showMainWindowCommand targets matches the main window label in tauri.conf.json
  2. Respect --start-hidden: skip the reveal when the user explicitly requested a hidden start
  3. Retry once after a short delay to cover startup races
  4. Log the raw error to distinguish 'window not found' from 'command not found'

Example fix

// before
try {
  await commands.showMainWindowCommand();
} catch (e) {
  console.warn("Failed to show main window for permission onboarding:", e);
}

// after
for (const delay of [0, 1000]) {
  try {
    if (delay) await new Promise((r) => setTimeout(r, delay));
    await commands.showMainWindowCommand();
    break;
  } catch (e) {
    if (delay) console.warn("Failed to show main window for permission onboarding:", e);
  }
}
Defensive patterns

Strategy: retry

Validate before calling

import { isTauri } from "@tauri-apps/api/core";
if (!isTauri()) return;

Try / catch

try { await commands.showMainWindowCommand(); }
catch (e) {
  console.warn("Failed to show main window for permission onboarding:", e);
  setTimeout(() => void commands.showMainWindowCommand().catch(() => {}), 1000);
}

Prevention

When it happens

Trigger: The invoke rejecting because the main window label was renamed/removed from tauri.conf.json while the command still targets the old label; invoking during app shutdown; the command missing from the invoke_handler in a trimmed build; browser-context dev where invoke always rejects.

Common situations: Window-label refactors; startup races on slow machines; --start-hidden runs where the window is expected to stay hidden and the call is arguably wrong anyway.

Related errors


AI-assisted analysis of cjpais/Handy@c89b7bf389 (2026-08-17). Data as JSON: /api/errors/03d387a809931f62. Report an issue: GitHub.