{"record":{"id":"965ebfc1aac1e61c","repo":"moeru-ai/airi","slug":"beat-sync-is-not-available-in-stage-pocket","errorCode":null,"errorMessage":"Beat Sync is not available in Stage Pocket","messagePattern":"Beat Sync is not available in Stage Pocket","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/stage-shared/src/beat-sync/detector.ts","lineNumber":256,"sourceCode":"}\n\nlet detector: BeatSyncDetector | undefined\nfunction getDetector() {\n  if (!isStageWeb())\n    throw new Error('getDetector() is only available in Stage Web environment')\n\n  if (!detector)\n    detector = createBeatSyncDetector({ env: StageEnvironment.Web })\n\n  return detector\n}\n\nlet context: ReturnType<typeof createContext> | undefined\n\nfunction installCapacitorHandlers(context: ReturnType<typeof createContext>) {\n  defineInvokeHandler(context, beatSyncToggleInvokeEventa, async (enabled) => {\n    if (enabled)\n      throw new Error('Beat Sync is not available in Stage Pocket')\n  })\n  defineInvokeHandler(context, beatSyncGetStateInvokeEventa, async () => ({ isActive: false }))\n  defineInvokeHandler(context, beatSyncUpdateParametersInvokeEventa, async () => {})\n  defineInvokeHandler(context, beatSyncGetInputByteFrequencyDataInvokeEventa, async () => {\n    return new Uint8Array(inputAnalyserFFTSize / 2)\n  })\n}\n\nfunction getContext() {\n  if (!context) {\n    context = createContext()\n\n    // Capacitor cannot capture system audio. Register every request handler so\n    // callers receive deterministic inactive results instead of pending forever.\n    if (isStageCapacitor())\n      installCapacitorHandlers(context)\n  }\n","sourceCodeStart":238,"sourceCodeEnd":274,"githubUrl":"https://github.com/moeru-ai/airi/blob/677329427f32468c74b17f3ec47eeca4e05bec65/packages/stage-shared/src/beat-sync/detector.ts#L238-L274","documentation":"On Stage Pocket (the Capacitor mobile build), beat-sync has no implementation, so the Eventa invoke handler for beatSyncToggleInvokeEventa is registered to throw this error whenever it is invoked with enabled=true (packages/stage-shared/src/beat-sync/detector.ts:256). It is a deliberate capability guard, not a bug: desktop capture analysis cannot run on the mobile platform.","triggerScenarios":"UI code shared across platforms calling the beat-sync toggle with enabled=true inside the Pocket build, or a settings page that was not platform-gated and lets the user flip the toggle on mobile.","commonSituations":"Reusing the desktop settings UI on mobile, feature flags that forget to exclude pocket, or code paths migrated without a platform check.","solutions":["Gate the toggle UI on platform (hide it on Stage Pocket) so the invoke never fires","Catch this error where toggle is invoked and show an 'unsupported on this device' notice","Use the state getters (beatSyncGetStateInvokeEventa returns isActive:false) to render the off state instead of toggling"],"exampleFix":"// before\nawait invoke(beatSyncToggleInvokeEventa, true) // throws on Pocket\n// after\nimport { isCapacitorNative } from '../utils/platform'\nif (!isCapacitorNative())\n  await invoke(beatSyncToggleInvokeEventa, true)","handlingStrategy":"validation","validationCode":"import { Capacitor } from '@capacitor/core'\n\nconst beatSyncSupported = !Capacitor.isNativePlatform() // Pocket = native Capacitor build\nif (beatSyncSupported)\n  await invoke(beatSyncToggleInvokeEventa, enabled)","typeGuard":"const isStagePocket = (): boolean => Capacitor.isNativePlatform()\n\nfunction supportsBeatSync(env: 'web' | 'tamagotchi' | 'pocket'): boolean {\n  return env !== 'pocket'\n}","tryCatchPattern":"try {\n  await invoke(beatSyncToggleInvokeEventa, true)\n}\ncatch (error) {\n  if (error instanceof Error && error.message === 'Beat Sync is not available in Stage Pocket') {\n    toast('Beat Sync is not supported on this device')\n    return\n  }\n  throw error\n}","preventionTips":["Gate the beat-sync toggle UI by platform before it can be enabled","Read state via beatSyncGetStateInvokeEventa instead of toggling on unsupported platforms","Add a feature matrix check when sharing settings pages across stages"],"tags":["platform","capacitor","stage-pocket","beat-sync","feature-gating"],"backgroundTag":"unsupported-platform-feature","analyzedSha":"677329427f32468c74b17f3ec47eeca4e05bec65","analyzedAt":"2026-08-18T17:29:58.153Z","contentChangedAt":"2026-08-18T17:29:58.153Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}