Description
A LanguageModelV4 stream can emit the standard { type: "error", error: value } part. In @ai-sdk/[email protected] and current main, doStreamStep() forwards that part to the writable stream but does not retain or throw its error value. The switch in packages/workflow/src/do-stream-step.ts has no error case, so consumption continues and the returned step result cannot expose the supplied failure.
toUIMessageChunk() separately converts the value to errorText, which is useful for UI delivery, but server-side WorkflowAgent.stream() still does not fail with the original supplied value. Consumers that need to classify a credential-safe, structured error supplied by model middleware therefore receive only a generic error finish (or no typed terminal value).
Expected behavior: when the model stream emits a standard error part, fail the model step / agent run with the supplied part.error value, while preserving real-time stream delivery as appropriate. An equivalent typed terminal field on the server-side result would also provide the necessary contract, but a generic finishReason: "error" is insufficient because it discards the safe error classification.
Reproduction
A focused doStreamStep test can mock experimental_streamLanguageModelCall with a stream containing: