moeru-ai/airi · error · Error
Web Speech API is not available in this environment. It requ
Error message
Web Speech API is not available in this environment. It requires a browser context with SpeechRecognition support (Chrome, Edge, Safari).
What it means
Thrown by createWebSpeechAPIProvider() when the running environment has no window object or window lacks both SpeechRecognition and webkitSpeechRecognition. The Web Speech API is a browser-only, vendor-specific capability; without it the provider cannot construct a transcription client, so construction aborts. This is an environment capability check, not a runtime error.
Source
Thrown at packages/stage-ui/src/libs/providers/providers/browser-web-speech-api/provider.ts:61
/**
* Web Speech API Speech Recognition provider
*
* This is a free, browser-native STT solution that requires no API keys.
* Available in Chrome, Edge, Safari, and other Chromium-based browsers.
*
* Limitations:
* - Only works in browser contexts (Electron renderer, web browsers)
* - Requires user permission for microphone access
* - Language support depends on browser implementation
* - Not available in Node.js or Tauri main process
*/
export function createWebSpeechAPIProvider(): TranscriptionProviderWithExtraOptions<string, WebSpeechAPIExtraOptions> {
// Check if Web Speech API is available
const isAvailable = typeof window !== 'undefined'
&& ('webkitSpeechRecognition' in window || 'SpeechRecognition' in window)
if (!isAvailable) {
throw new Error('Web Speech API is not available in this environment. It requires a browser context with SpeechRecognition support (Chrome, Edge, Safari).')
}
const SpeechRecognition = (window as any).SpeechRecognition || (window as any).webkitSpeechRecognition
return {
transcription: (model: string, extraOptions?: WebSpeechAPIExtraOptions) => {
return {
baseURL: 'about:blank', // Web Speech API doesn't use HTTP endpoints
model: model || 'web-speech-api',
fetch: async (_request: RequestInfo | URL, _init?: RequestInit) => {
// Web Speech API does not support file-based transcription - it only supports live streaming
// Check if a file is provided in the request body and reject it
if (_init?.body) {
// If body is FormData, it likely contains a file
// If body is a Blob/File, it's definitely a file
const body = _init.body
if (body instanceof FormData || body instanceof Blob || body instanceof File) {
const error = new Error('Web Speech API does not support file-based transcription. It only supports live streaming from a MediaStream. Please use the streaming transcription API or select a different provider that supports file-based transcription.')View on GitHub (pinned to 27111382b4)
Solutions
- Only construct the provider in a supported browser renderer context (Chromium-based browser, Edge, Safari, Electron renderer with the API enabled).
- Guard construction: check 'SpeechRecognition' in window || 'webkitSpeechRecognition' in window before calling createWebSpeechAPIProvider().
- In Firefox or unsupported environments, choose a different transcription provider (e.g. Whisper, Aliyun NLS).
- For SSR/build, dynamic-import the provider inside an onMounted or client-only guard so it is never evaluated in Node.
Example fix
// before
const provider = createWebSpeechAPIProvider()
// after
const canUseWebSpeech = typeof window !== 'undefined'
&& ('SpeechRecognition' in window || 'webkitSpeechRecognition' in window)
if (!canUseWebSpeech)
throw new Error('Web Speech API unsupported in this browser; pick another transcription provider')
const provider = createWebSpeechAPIProvider() Defensive patterns
Strategy: type-guard
Validate before calling
function isWebSpeechSupported(): boolean {
return typeof window !== 'undefined'
&& ('webkitSpeechRecognition' in window || 'SpeechRecognition' in window)
}
// before constructing the provider:
if (!isWebSpeechSupported()) {
// pick another transcription provider; do not call createWebSpeechAPIProvider()
} Type guard
function isWebSpeechSupported(): boolean {
return typeof window !== 'undefined'
&& ('webkitSpeechRecognition' in window || 'SpeechRecognition' in window)
} Try / catch
try {
const provider = createWebSpeechAPIProvider()
}
catch (err) {
if (err instanceof Error && err.message.startsWith('Web Speech API is not available')) {
// fall back to a server-side transcription provider (Whisper, Aliyun NLS)
}
else throw err
} Prevention
- Dynamic-import the provider inside onMounted/client-only guards so SSR/build never evaluates it.
- Feature-detect SpeechRecognition before offering Web Speech as a transcription option.
- In Firefox, do not surface Web Speech as an available provider.
When it happens
Trigger: createWebSpeechAPIProvider() is called where typeof window === 'undefined' (Node.js, SSR, Tauri/Electron main process, a Web Worker) or in a browser without SpeechRecognition (Firefox, some Chromium embedded views with the flag disabled).
Common situations: Importing the provider during SSR/Node build or in the Electron main process. Running in Firefox, which lacks SpeechRecognition. Headless test environment (jsdom) without the API. Embedded WebView with the speech API disabled.
Related errors
- Replicate provider is not configured. Missing API Key.
- No active source selected
- The first `cap run` argument must be `ios` or `android`.
- CAP_VITE_CAP_ARGS_JSON must be a JSON string array.
- Vision provider/model not configured
AI-assisted analysis of moeru-ai/airi@27111382b4 (2026-08-12).
Data as JSON: /api/errors/60fa253f0ca838ff.
Report an issue: GitHub.