microsoft/semantic-kernel · error · InvalidOperationException

Response failed

Error message

Response failed

What it means

Thrown by BedrockChatCompletionClient.GenerateChatMessageAsync after a ConverseAsync call returned without throwing, but the response was null or had no Output/Message. It is an InvalidOperationException because the call technically completed but produced no usable content. This indicates the runtime returned an empty/malformed ConverseResponse rather than surfacing an HTTP error.

Source

Thrown at dotnet/src/Connectors/Connectors.Amazon/Bedrock/Core/Clients/BedrockChatCompletionClient.cs:106

                activity.SetError(ex);
                if (response != null)
                {
                    activityStatus = BedrockClientUtilities.ConvertHttpStatusCodeToActivityStatusCode(response.HttpStatusCode);
                    activity.SetStatus(activityStatus);
                    activity.SetInputTokensUsage(response?.Usage?.InputTokens ?? default);
                    activity.SetOutputTokensUsage(response?.Usage?.OutputTokens ?? default);
                }
                else
                {
                    // If response is null, set a default status or leave it unset
                    activity.SetStatus(ActivityStatusCode.Error); // or ActivityStatusCode.Unset
                }
            }
            throw;
        }
        if ((response == null) || response.Output == null || response.Output.Message == null)
        {
            throw new InvalidOperationException("Response failed");
        }
        IReadOnlyList<ChatMessageContent> chatMessages = this.ConvertToMessageContent(response).ToList();
        activityStatus = BedrockClientUtilities.ConvertHttpStatusCodeToActivityStatusCode(response.HttpStatusCode);
        activity?.SetStatus(activityStatus);
        activity?.SetCompletionResponse(chatMessages, response.Usage.InputTokens, response.Usage.OutputTokens);
        return chatMessages;
    }

    /// <summary>
    /// Converts the ConverseResponse object as outputted by the Bedrock Runtime API call to a ChatMessageContent for the Semantic Kernel.
    /// </summary>
    /// <param name="response"> ConverseResponse object outputted by Bedrock. </param>
    /// <returns>List of ChatMessageContent objects</returns>
    private ChatMessageContent[] ConvertToMessageContent(ConverseResponse response)
    {
        if (response.Output.Message == null)
        {
            return [];

View on GitHub (pinned to c028a0c7dc)

Solutions

  1. Retry the identical request once (transient empty responses do occur); wrap the chat call in try/catch for InvalidOperationException.
  2. Inspect the model's guardrail/content-filter settings and disable or relax filters that are stripping the message.
  3. Confirm the modelId is Converse-API-compatible (most chat/text models are; some embedding-only or legacy ids are not).
  4. Enable SK logging to capture the underlying response.HttpStatusCode captured on the activity before the throw.

Example fix

// before
var reply = await chat.GetChatMessageContentAsync(history);

// after
try
{
    var reply = await chat.GetChatMessageContentAsync(history);
}
catch (InvalidOperationException ex) when (ex.Message == "Response failed")
{
    _logger.LogWarning("Bedrock returned an empty ConverseResponse for {ModelId}; retrying", modelId);
    reply = await chat.GetChatMessageContentAsync(history);
}
Defensive patterns

Strategy: retry

Try / catch

async Task<T> WithBedrockRetry<T>(Func<Task<T>> fn, int attempts = 2)
{
    for (int i = 0; ; i++)
    {
        try { return await fn(); }
        catch (InvalidOperationException ex) when (ex.Message == "Response failed" && i < attempts - 1)
        { _logger.LogWarning("Empty Bedrock chat response, retrying"); }
    }
}

Prevention

When it happens

Trigger: Calling chat completion against a Bedrock model whose ConverseResponse came back with null Output or null Output.Message, e.g. a model that returned only guardrail/intervention metadata, a throttled but non-exception 200 with empty body, or a response shaped by a content-filter that dropped the message. Also seen with incompatible model ids that the Converse API accepts but returns no assistant message for.

Common situations: Content filtering / guardrails configured on the Bedrock model that empty the output. Hitting a non-GenAI or non-Converse-supported model id through the chat path. Transient Bedrock runtime quirk returning a null Output. Region or inference-profile mismatch producing empty content.

Related errors


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