moeru-ai/airi · warning

Web Speech API failed to restart, creating new instance:

Error message

Web Speech API failed to restart, creating new instance:

What it means

In continuous mode the provider restarts recognition after onend by calling currentRecognition.start() inside a setTimeout. start() throws synchronously (typically InvalidStateError: 'recognition has already started') when the old instance is still active or in a bad lifecycle state; this warning logs that throw and falls back to createAndStartNewRecognitionInstance().

Source

Thrown at packages/stage-ui/src/libs/providers/providers/browser-web-speech-api/provider.ts:303

    options?.onSpeechEnd?.(fullText)
  }

  recognition.onend = () => {
    console.info('Web Speech API recognition ended. Continuous mode:', options?.continuous !== false, 'Aborted:', options?.abortSignal?.aborted)

    // If continuous mode and not aborted, restart recognition
    if (options?.continuous !== false && !options?.abortSignal?.aborted) {
      // Use the current recognitionInstance to ensure we're using the correct instance
      const currentRecognition = recognitionInstance || recognition

      // Small delay before restarting to avoid rapid restart loops
      setTimeout(() => {
        try {
          currentRecognition.start()
          console.info('Web Speech API recognition restarted (continuous mode)')
        }
        catch (err) {
          console.warn('Web Speech API failed to restart, creating new instance:', err)
          // If restart fails, create a new instance
          try {
            createAndStartNewRecognitionInstance(recognition)
            console.info('Web Speech API created new instance and started')
          }
          catch (newErr) {
            console.error('Web Speech API failed to create new instance:', newErr)
            const error = new Error(`Failed to restart recognition: ${errorMessageFromValue(newErr)}`)
            fullStreamCtrl?.error(error)
            textStreamCtrl?.error(error)
            deferredText.reject(error)
            deferredText.isRejected = true
          }
        }
      }, 100)
    }
    else {
      // Don't try to enqueue/close if the stream has already been aborted/errored

View on GitHub (pinned to 677329427f)

Solutions

  1. Rely on the built-in fallback: the provider already creates a fresh instance when restart throws; verify the following 'created new instance and started' log appears.
  2. Track a stopped/started flag around recognition lifecycle to avoid calling start() on an active instance.
  3. Debounce rapid start/stop toggles in the UI to avoid restart races.
  4. If creating the new instance also fails, see the follow-up 'failed to create new instance' error path — that indicates a deeper permission/service problem.

Example fix

// before
setTimeout(() => {
  try {
    currentRecognition.start()
  }
  catch (err) {
    console.warn('Web Speech API failed to restart, creating new instance:', err)
    createAndStartNewRecognitionInstance(recognition)
  }
})

// after — stop the old instance first so start() cannot hit InvalidStateError
setTimeout(() => {
  try {
    currentRecognition.abort()
    currentRecognition.start()
  }
  catch (err) {
    console.warn('Web Speech API failed to restart, creating new instance:', err)
    createAndStartNewRecognitionInstance(recognition)
  }
})
Defensive patterns

Strategy: fallback

Validate before calling

function isRecognitionStopped(rec: SpeechRecognition): boolean {
  // no readyState in the spec; track via flags set in onend/onstart
  return !recognitionActive
}

Try / catch

try {
  currentRecognition.start()
}
catch {
  // fall back to a fresh instance (provider already does this)
  createAndStartNewRecognitionInstance(recognition)
}

Prevention

When it happens

Trigger: onend fires while the recognition object is not fully stopped, or a previous restart already succeeded, so the delayed start() hits an already-started instance — common when Chrome fires onend/onstart in quick succession in continuous mode.

Common situations: Long-running continuous dictation where the engine auto-restarts; Chrome version changes altering onend timing; rapid toggle of listening on/off; two restart paths (timer + user action) racing.

Related errors


AI-assisted analysis of moeru-ai/airi@677329427f (2026-08-18). Data as JSON: /api/errors/c18b3e3ea30fbd9e. Report an issue: GitHub.