{"record":{"id":"2037e7ae67f1c379","repo":"iOfficeAI/AionUi","slug":"audioworkletunavailableerror","errorCode":null,"errorMessage":"AudioWorkletUnavailableError","messagePattern":"AudioWorkletUnavailableError","errorType":"exception","errorClass":"AudioWorkletUnavailableError","httpStatus":null,"severity":"warning","filePath":"packages/desktop/src/renderer/services/speech/pcmRecorder.ts","lineNumber":162,"sourceCode":"}): Promise<PcmRecorderHandle> => {\n  const stream = await navigator.mediaDevices.getUserMedia({ audio: true });\n  const releaseMic = () => stream.getTracks().forEach((track) => track.stop());\n\n  // Request 24kHz directly; Chromium honors it, but some platforms ignore the\n  // hint, so the actual context.sampleRate is checked below.\n  let context: AudioContext;\n  try {\n    context = new AudioContext({ sampleRate: STREAM_SAMPLE_RATE });\n  } catch (error) {\n    releaseMic();\n    throw error;\n  }\n  const closeContext = (): Promise<void> => context.close().catch((): void => undefined);\n\n  if (!context.audioWorklet) {\n    await closeContext();\n    releaseMic();\n    throw new AudioWorkletUnavailableError();\n  }\n\n  const workletUrl = URL.createObjectURL(new Blob([WORKLET_SOURCE], { type: 'application/javascript' }));\n  try {\n    await context.audioWorklet.addModule(workletUrl);\n  } catch (error) {\n    await closeContext();\n    releaseMic();\n    throw error;\n  } finally {\n    URL.revokeObjectURL(workletUrl);\n  }\n\n  const contextRate = context.sampleRate;\n  const needsResample = contextRate !== STREAM_SAMPLE_RATE;\n  // Input samples (at context rate) needed to produce one 200ms output chunk.\n  const chunkInputSamples = Math.max(1, Math.round((STREAM_CHUNK_SAMPLES * contextRate) / STREAM_SAMPLE_RATE));\n","sourceCodeStart":144,"sourceCodeEnd":180,"githubUrl":"https://github.com/iOfficeAI/AionUi/blob/711aa0550ee183ea495dc33e2c05c7943b70a60a/packages/desktop/src/renderer/services/speech/pcmRecorder.ts#L144-L180","documentation":"`createPcmRecorder` needs the Web Audio `AudioWorklet` API to capture PCM frames; on browsers/electron builds where `context.audioWorklet` is undefined it closes the AudioContext, releases the mic stream, and throws `AudioWorkletUnavailableError`. This is a feature-detection failure, not a runtime crash.","triggerScenarios":"Creating the PCM recorder in an environment whose AudioContext lacks the `audioWorklet` property — older Chromium/Electron versions (pre-Chrome 66), non-secure/non-standard embedding contexts, or environments with the WebAudio API partially polyfilled/stripped.","commonSituations":"Running the app on an old Electron/Chromium runtime; audio capture in an iframe or webview without proper feature support; test environments (jsdom) lacking real WebAudio; browser-polyfill conflicts removing audioWorklet.","solutions":["Upgrade the Electron/Chromium runtime to a version supporting AudioWorklet (Chrome 66+/Electron 3+)","Feature-detect before starting capture and fall back to a non-worklet recorder (ScriptProcessorNode) or disable PCM speech features","Verify the page is not running in a restricted context that strips WebAudio features","In tests, mock AudioContext with an audioWorklet stub instead of exercising the real path"],"exampleFix":"// before\nif (!context.audioWorklet) {\n  await closeContext();\n  releaseMic();\n  throw new AudioWorkletUnavailableError();\n}\n\n// after (pre-check and show guidance)\nif (!('audioWorklet' in new AudioContext())) {\n  showToast(t('speech.pcmUnsupported')); // and skip the record button\n}","handlingStrategy":"type-guard","validationCode":"const ctx = new AudioContext();\nif (!('audioWorklet' in ctx)) { ctx.close(); /* fall back or disable PCM UI */ }","typeGuard":"const supportsAudioWorklet = (): boolean =>\n  typeof AudioContext !== 'undefined' && 'audioWorklet' in AudioContext.prototype;","tryCatchPattern":"catch (e) { if (e instanceof AudioWorkletUnavailableError) disablePcmFeatures(); else throw e; }","preventionTips":["Feature-detect AudioWorklet before showing the record button","Keep Electron/Chromium updated; stub audioWorklet in jsdom tests"],"tags":["web-audio","audioworklet","speech","feature-detection","browser-support"],"backgroundTag":"browser-api-unsupported","analyzedSha":"711aa0550ee183ea495dc33e2c05c7943b70a60a","analyzedAt":"2026-08-28T07:56:06.558Z","schemaVersion":2},"datasetVersion":"2026-08-28T11:17:15.048Z"}