moeru-ai/airi · error · TypeError

Apple Speech live transcription requires an audio stream.

Error message

Apple Speech live transcription requires an audio stream.

What it means

executeAppleSpeechStream requires a live audio input; options.inputAudioStream must be present because Apple Speech live transcription consumes a continuous PCM stream fed to the native recognizer. A one-shot request shape (e.g. only a request payload with no stream) is rejected with a TypeError.

Source

Thrown at packages/stage-ui/src/libs/providers/providers/apple-speech/index.ts:195

    await writer.abort(error).catch(() => {})
    throw error
  }
  finally {
    reader.releaseLock()
  }
}

/**
 * Adapts AIRI's mono PCM16 VAD stream to Apple Speech live transcription.
 *
 * The Provider boundary converts each audio chunk and maps Apple replacement
 * events to AIRI transcript snapshots.
 */
export function executeAppleSpeechStream(options: AppleSpeechStreamOptions): AIRIStreamTranscriptionResult
export function executeAppleSpeechStream(options: StreamTranscriptionOptions): AIRIStreamTranscriptionResult
export function executeAppleSpeechStream(options: StreamTranscriptionOptions): AIRIStreamTranscriptionResult {
  if (!options.inputAudioStream)
    throw new TypeError('Apple Speech live transcription requires an audio stream.')
  if (!isAppleSpeechStreamRequest(options))
    throw new TypeError('Apple Speech live transcription requires a native stream request.')

  const inputSampleRate = options.inputSampleRate ?? 16000
  const live = streamAppleSpeechTranscription({
    ...options,
    inputSampleRate,
  })
  const inputPump = pumpPcm16Input(options.inputAudioStream, live.input.getWriter())
  void inputPump.catch(() => {})

  return {
    fullStream: live.fullStream.pipeThrough(new TransformStream({
      transform(event, controller) {
        controller.enqueue(appleEventSnapshot(event))
      },
    })),
    text: Promise.all([live.text, inputPump]).then(([text]) => text),

View on GitHub (pinned to f679616c34)

Solutions

  1. Pass an inputAudioStream (e.g. a MediaStream/MediaStreamTrack audio pipe) in options when calling executeAppleSpeechStream.
  2. If your options object is generic, branch: use the stream API only when audio streaming is available, otherwise use a non-streaming transcription call.
  3. Check upstream option construction for a dropped/renamed inputAudioStream field after refactors.

Example fix

// before
const result = executeAppleSpeechStream({ request })

// after
const result = executeAppleSpeechStream({
  request,
  inputAudioStream: micAudioStream,
})
Defensive patterns

Strategy: validation

Validate before calling

if (!options.inputAudioStream) {
  throw new TypeError('Caller must supply an audio stream before starting live transcription.')
}
const result = executeAppleSpeechStream(options)

Type guard

function isStreamTranscriptionReady(options: StreamTranscriptionOptions): boolean {
  return options.inputAudioStream != null
}

Try / catch

null

Prevention

When it happens

Trigger: Calling executeAppleSpeechStream with options that lack inputAudioStream, e.g. passing a plain StreamTranscriptionOptions object intended for another provider, or building AppleSpeechStreamOptions manually and forgetting the stream.

Common situations: Generic provider-agnostic code passing a shared options object to every transcription provider; refactoring that renamed or moved the stream field; a caller assuming the provider polls a microphone itself instead of receiving the stream.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


AI-assisted analysis of moeru-ai/airi@f679616c34 (2026-08-28). Data as JSON: /api/errors/5aa2294f91a738e4. Report an issue: GitHub.