moeru-ai/airi · error
Aliyun NLS returned a non-streaming result unexpectedly.
Error message
Aliyun NLS returned a non-streaming result unexpectedly.
What it means
Invariant assertion in the Aliyun NLS streaming playground: `hearingStore.transcription(...)` returns a discriminated union (`HearingTranscriptionResult`) whose `mode` is 'stream' when the realtime path was taken (packages/stage-ui/src/stores/modules/hearing.ts:459-493 requires stream capabilities, a resolved stream executor, and the `inputAudioStream` the page passes) and 'generate' for the buffered path. The page then does `result.text` plumbing and PCM streaming, which only exists for 'stream', so any other mode is rejected loudly instead of being mis-consumed.
Source
Thrown at packages/stage-pages/src/pages/settings/providers/transcription/aliyun-nls-transcription.vue:260
},
},
onSessionTerminated: async (error?: unknown) => {
if (error)
errorMessage.value = errorMessageFromValue(error)
isStreaming.value = false
transcriptionAbortController.value = undefined
},
sessionOptions: {
format: 'pcm',
sample_rate: SAMPLE_RATE,
enable_punctuation_prediction: true,
},
},
},
)
if (result.mode !== 'stream')
throw new Error('Aliyun NLS returned a non-streaming result unexpectedly.')
activeTranscription.value = result
transcriptionTextPromise.value = result.text
.catch((error) => {
errorMessage.value = errorMessageFromValue(error)
throw error
})
const stream = await navigator.mediaDevices.getUserMedia({
audio: {
channelCount: 1,
sampleRate: SAMPLE_RATE,
echoCancellation: true,
noiseSuppression: true,
autoGainControl: true,
},
})
View on GitHub (pinned to 677329427f)
Solutions
- Confirm the provider definition still declares transcription capabilities streamOutput: true and streamInput: true (as aliyun-nls does) and that the page passes `{ inputAudioStream }`.
- Check `resolveStreamTranscriptionExecutor(providerId)` in the console/debugger — a null executor is the usual reason the store fell back to buffered mode.
- Update or align stage-ui and stage-pages to the same version so feature detection and the page contract match.
- If buffered results are acceptable for your flow, handle `mode === 'generate'` explicitly (read `result.text`/segments) instead of throwing.
- Report the mismatch as a bug — this assertion exists to expose exactly this drift.
Example fix
// before
if (result.mode !== 'stream')
throw new Error('Aliyun NLS returned a non-streaming result unexpectedly.')
// after (keep the invariant, but include diagnosis hints)
if (result.mode !== 'stream')
throw new Error(`Aliyun NLS returned mode '${result.mode}' — streaming capabilities/executor drifted. Check provider definition streamOutput/streamInput and resolveStreamTranscriptionExecutor('${providerId}').`) Defensive patterns
Strategy: type-guard
Validate before calling
const features = providersStore.getTranscriptionFeatures(providerId)
if (!features.supportsStreamOutput || !features.supportsStreamInput)
throw new Error('This page requires a provider with streaming transcription capabilities') Type guard
function isStreamTranscriptionResult(r: HearingTranscriptionResult): r is Extract<HearingTranscriptionResult, { mode: 'stream' }> {
return r.mode === 'stream'
}
// usage: if (!isStreamTranscriptionResult(result)) throw new Error('...') Try / catch
try {
const result = await hearingStore.transcription(providerId, provider, defaultModel, { inputAudioStream: audioStream }, undefined, { ... })
if (result.mode !== 'stream') throw new Error('unexpected buffered result')
}
catch (error) { errorMessage.value = errorMessageFromValue(error) } Prevention
- Keep provider capability metadata (streamInput/streamOutput) and page expectations in sync — this assertion exists to catch drift.
- Narrow the result union with a type guard before consuming stream-only fields.
- When reusing this page for new providers, verify the stream executor resolves for the provider id first.
When it happens
Trigger: The stream executor not resolving for the provider id (`resolveStreamTranscriptionExecutor` returning null) while buffered generation still runs — e.g. capability metadata drift between the provider definition and the runtime; a refactor/change making `getTranscriptionFeatures` report streamOutput false so the call falls into the buffered branch; a File input sneaking in alongside stream expectations; future providers reusing this page without stream support.
Common situations: Definition capabilities edited (streamOutput/streamInput flags) without updating the page; custom provider ids colliding with the executor registry; version skew between stage-ui store and stage-pages during upgrades; tests exercising the page with a mocked buffered transcription result.
Related errors
- Streaming transcription request failed with status ${respons
- Streaming transcription response is missing a readable body.
- Failed to initialize Aliyun NLS provider.
- [Hearing Pipeline] Stream input not supported
- Web Speech API is not available in this environment. It requ
AI-assisted analysis of moeru-ai/airi@677329427f (2026-08-18).
Data as JSON: /api/errors/475e303bb1a8288a.
Report an issue: GitHub.