{"record":{"id":"552f89f530139476","repo":"cjpais/Handy","slug":"failed-to-check-macos-permissions","errorCode":null,"errorMessage":"Failed to check macOS permissions:","messagePattern":"Failed to check macOS permissions:","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"src/App.tsx","lineNumber":208,"sourceCode":"      const currentPlatform = platform();\n\n      if (hasCompletedOnboarding) {\n        // Returning user - check if they need to grant permissions first\n        setIsReturningUser(true);\n\n        if (currentPlatform === \"macos\") {\n          try {\n            const [hasAccessibility, hasMicrophone] = await Promise.all([\n              checkAccessibilityPermission(),\n              checkMicrophonePermission(),\n            ]);\n            if (!hasAccessibility || !hasMicrophone) {\n              await revealMainWindowForPermissions();\n              setOnboardingStep(\"accessibility\");\n              return;\n            }\n          } catch (e) {\n            console.warn(\"Failed to check macOS permissions:\", e);\n            // If we can't check, proceed to main app and let them fix it there\n          }\n        }\n\n        if (currentPlatform === \"windows\") {\n          try {\n            const microphoneStatus =\n              await commands.getWindowsMicrophonePermissionStatus();\n            if (\n              microphoneStatus.supported &&\n              microphoneStatus.overall_access === \"denied\"\n            ) {\n              await revealMainWindowForPermissions();\n              setOnboardingStep(\"accessibility\");\n              return;\n            }\n          } catch (e) {\n            console.warn(\"Failed to check Windows microphone permissions:\", e);","sourceCodeStart":190,"sourceCodeEnd":226,"githubUrl":"https://github.com/cjpais/Handy/blob/c89b7bf38974ad317177389f5bfe28236f0d64e3/src/App.tsx#L190-L226","documentation":"During startup onboarding checks, App.tsx calls the macOS-specific commands checkAccessibilityPermission and checkMicrophonePermission. If either invoke rejects, this catch logs the failure and deliberately continues into the main app so the user can fix permissions later from settings — a fail-open policy that trades strictness for not bricking first run.","triggerScenarios":"The invoke rejecting when the backend is not yet ready at component mount; the commands not being registered (e.g. a non-macOS feature build that still passes the platform() check); an underlying macOS API error from the permission query; running the webview in a plain browser during development.","commonSituations":"Frontend development in Vite without Tauri; early-startup races; development builds where plugin-os reports 'macos' but the permission commands are cfg-gated out.","solutions":["Verify the two commands are compiled and registered for macOS builds and listed in invoke_handler","Guard the block with isTauri() so browser dev does not trigger it","Re-check permissions once the app emits ready / the window gains focus, instead of a single mount-time call","If failing open is unacceptable for your fork, route to setOnboardingStep('accessibility') on error instead of proceeding"],"exampleFix":"// before\n} catch (e) {\n  console.warn(\"Failed to check macOS permissions:\", e);\n  // If we can't check, proceed to main app and let them fix it there\n}\n\n// after\nimport { isTauri } from \"@tauri-apps/api/core\";\n// ...\n} catch (e) {\n  console.warn(\"Failed to check macOS permissions:\", e);\n  if (isTauri()) {\n    await revealMainWindowForPermissions();\n    setOnboardingStep(\"accessibility\"); // fail toward the permission UI, not silently open\n    return;\n  }\n}","handlingStrategy":"try-catch","validationCode":"import { isTauri } from \"@tauri-apps/api/core\";\nif (!isTauri()) { setOnboardingStep(\"done\"); return; }","typeGuard":null,"tryCatchPattern":"try {\n  const [a, m] = await Promise.all([checkAccessibilityPermission(), checkMicrophonePermission()]);\n  /* route on results */\n} catch (e) {\n  console.warn(\"Failed to check macOS permissions:\", e);\n  // choose fail-open (current) or fail-to-permission-UI deliberately\n  await revealMainWindowForPermissions();\n  setOnboardingStep(\"accessibility\");\n}","preventionTips":["Gate permission checks on isTauri() and on the platform() result matching the command's cfg target","Re-check permissions on window focus rather than only at mount, to survive startup races","Document the fail-open decision so future changes do not silently remove it"],"tags":["tauri","macos","permissions","accessibility","onboarding"],"backgroundTag":"os-permission-check-failed","analyzedSha":"c89b7bf38974ad317177389f5bfe28236f0d64e3","analyzedAt":"2026-08-17T10:29:55.597Z","contentChangedAt":"2026-08-17T10:29:55.597Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}