microsoft/semantic-kernel · error · NotSupportedException

Streaming not supported by this model.

Error message

Streaming not supported by this model.

What it means

Thrown by AI21JurassicService.GetTextStreamOutput. AI21 Jurassic (j2-) models do not support streaming, so any streaming text-generation call against a j2- model hits this NotSupportedException. The interface method is implemented but explicitly forbidden for this provider.

Source

Thrown at dotnet/src/Connectors/Connectors.Amazon/Bedrock/Core/Models/AI21Labs/AI21JurassicService.cs:55

    public IReadOnlyList<TextContent> GetInvokeResponseBody(InvokeModelResponse response)
    {
        using var reader = new StreamReader(response.Body);
        var responseBody = JsonSerializer.Deserialize<AI21JurassicResponse>(reader.ReadToEnd());

        if (responseBody?.Completions is not { Count: > 0 })
        {
            return [];
        }

        return responseBody.Completions
            .Select(completion => new TextContent(completion.Data?.Text, innerContent: responseBody))
            .ToList();
    }

    /// <inheritdoc/>
    public IEnumerable<StreamingTextContent> GetTextStreamOutput(JsonNode chunk)
    {
        throw new NotSupportedException("Streaming not supported by this model.");
    }
}

View on GitHub (pinned to c028a0c7dc)

Solutions

  1. Use a non-streaming text-generation call (GetTextContentAsync / InvokeAsync) for AI21 j2 models.
  2. Switch to a streaming-capable model (Claude, Titan, Meta Llama, Mistral, Cohere command-r, AI21 Jamba) if streaming is required.
  3. Guard the modelId before choosing the streaming path and fall back to non-streaming for j2-.

Example fix

// before
await foreach (var chunk in kernel.InvokeStreamingAsync<StreamingTextContent>(promptFunc)) { /* ... */ }
// throws when modelId = ai21.j2-ultra

// after
bool streamingCapable = !modelId.Contains("j2-", StringComparison.OrdinalIgnoreCase);
if (streamingCapable)
    await foreach (var chunk in kernel.InvokeStreamingAsync<StreamingTextContent>(promptFunc)) { /* ... */ }
else
    await kernel.InvokeAsync(promptFunc);
Defensive patterns

Strategy: type-guard

Validate before calling

bool SupportsStreaming(string modelId)
{
    var p = modelId.Split('.');
    if (p.Length < 2) return true;
    var provider = p[0].ToUpperInvariant();
    var name = p[1].ToUpperInvariant();
    // AI21 Jurassic (j2-) is the only shipped text model that does not stream
    return !(provider == "AI21" && name.StartsWith("J2-"));
}

Type guard

bool IsStreamingCapable(string modelId)
{
    var parts = modelId.Split('.');
    return !(parts.Length > 1 && parts[0].Equals("ai21", StringComparison.OrdinalIgnoreCase)
             && parts[1].StartsWith("j2-", StringComparison.OrdinalIgnoreCase));
}

Try / catch

try { await foreach (var c in kernel.InvokeStreamingAsync<StreamingTextContent>(fn, ct)) { /* ... */ } }
catch (NotSupportedException ex) when (ex.Message == "Streaming not supported by this model.")
{ _logger.LogInformation("Model {ModelId} cannot stream; using non-streaming call", modelId); await kernel.InvokeAsync(fn); }

Prevention

When it happens

Trigger: Calling a streaming text API (GetStreamingTextContentsAsync / InvokeStreamingAsync) with a modelId whose provider resolves to AI21 Jurassic, e.g. 'ai21.j2-ultra' or 'ai21.j2-mid'. BedrockServiceFactory.CreateTextGenerationService maps 'j2-' to AI21JurassicService, and its GetTextStreamOutput always throws.

Common situations: Applying the same streaming code path used for Claude/Titan to an AI21 j2 model. Migrating a streaming pipeline onto a Jurassic model. Config-driven model selection where the config points at a non-streaming model.

Related errors


AI-assisted analysis of microsoft/semantic-kernel@c028a0c7dc (2026-08-13). Data as JSON: /api/errors/58463d93ac735e60. Report an issue: GitHub.