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
- Confirm the label showMainWindowCommand targets matches the main window label in tauri.conf.json
- Respect --start-hidden: skip the reveal when the user explicitly requested a hidden start
- Retry once after a short delay to cover startup races
- 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
- Keep window labels in tauri.conf.json in sync with commands that reference them
- Respect --start-hidden so the reveal is not fought by the user's own launch flag
- Distinguish 'window not found' from 'command not found' in the logged error before changing code
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
- Failed to check Windows microphone permissions:
- Failed to sync language from settings:
- Failed to sync theme from settings:
- Failed to check macOS permissions:
- Failed to check Windows microphone permissions:
AI-assisted analysis of cjpais/Handy@c89b7bf389 (2026-08-17).
Data as JSON: /api/errors/03d387a809931f62.
Report an issue: GitHub.