vercel/ai · error · UnsupportedFunctionalityError

'element streams in object mode' functionality not supported

Error message

'element streams in object mode' functionality not supported.

What it means

This UnsupportedFunctionalityError is thrown by the object output strategy when an element stream is requested while `streamObject` runs in the default `output: 'object'` mode. Element streams only exist for array outputs, because there are no per-element items to emit from a single object. The strategy intentionally rejects the call instead of returning a stub stream.

Source

Thrown at packages/ai/src/generate-object/output-strategy.ts:127

  async validatePartialResult({ value, textDelta }) {
    return {
      success: true,
      value: {
        // Note: currently no validation of partial results:
        partial: value as DeepPartial<OBJECT>,
        textDelta,
      },
    };
  },

  async validateFinalResult(
    value: JSONValue | undefined,
  ): Promise<ValidationResult<OBJECT>> {
    return safeValidateTypes({ value, schema });
  },

  createElementStream() {
    throw new UnsupportedFunctionalityError({
      functionality: 'element streams in object mode',
    });
  },
});

const arrayOutputStrategy = <ELEMENT>(
  schema: Schema<ELEMENT>,
): OutputStrategy<ELEMENT[], ELEMENT[], AsyncIterableStream<ELEMENT>> => {
  return {
    type: 'array',

    // wrap in object that contains array of elements, since most LLMs will not
    // be able to generate an array directly:
    // possible future optimization: use arrays directly when model supports grammar-guided generation
    jsonSchema: async () => {
      // keep root-level definitions available to root-relative references:
      const {
        $schema: _$schema,

View on GitHub (pinned to 69428b1f8b)

Solutions

  1. Use `output: 'array'` with a schema for the element type if you need `elementStream`.
  2. In object mode, consume `partialObjectStream`, `object`, or `textStream` instead of `elementStream`.
  3. Fix types (`as any` removal) so the compiler flags `elementStream` access in object mode.

Example fix

// before
const result = streamObject({ model, prompt, schema });
for await (const el of result.elementStream) { ... }

// after
const result = streamObject({
  model,
  prompt,
  output: 'array',
  schema: z.object({ name: z.string() }),
});
for await (const el of result.elementStream) { ... }
Defensive patterns

Strategy: type-guard

Validate before calling

// only iterate elementStream for array outputs
const result = streamObject({ model, prompt, output: mode, schema });
if (mode !== 'array') console.warn('elementStream unavailable in', mode);

Type guard

function hasElementStream(r: unknown): r is { elementStream: AsyncIterable<unknown> } {
  return typeof r === 'object' && r !== null && 'elementStream' in r;
}

Try / catch

try {
  for await (const el of result.elementStream) { /* ... */ }
} catch (e) {
  if (UnsupportedFunctionalityError.isInstance(e)) {
    const obj = await result.object; // fallback for object mode
  } else throw e;
}

Prevention

When it happens

Trigger: Calling `streamObject({ output: 'object', schema, ... })` (or omitting `output`) and then iterating `result.elementStream`. Happens via `as any` casts, untyped JS callers, generic wrapper helpers that always expose `elementStream`, or copy-pasted streaming code from an array-mode example.

Common situations: Copy-pasting array-mode streaming code into object-mode code; generic response handlers that conditionally read `elementStream` regardless of output mode; JavaScript projects without type checking.

Related errors


AI-assisted analysis of vercel/ai@69428b1f8b (2026-08-30). Data as JSON: /api/errors/48d53b3bcafad1c7. Report an issue: GitHub.