microsoft/semantic-kernel · error · HttpOperationException

Failed to invoke agent. Status code: {invokeAgentResponse.Ht

Error message

Failed to invoke agent. Status code: {invokeAgentResponse.HttpStatusCode}

What it means

Thrown when InvokeAgentAsync returns an HTTP status code other than 200 OK. This HttpOperationException reports the actual status code so the caller can distinguish auth failures (401/403), not-found (404), throttling (429), and server errors (5xx). The check happens before any stream processing begins.

Source

Thrown at dotnet/src/Agents/Bedrock/Extensions/BedrockAgentInvokeExtensions.cs:43

        InvokeAgentRequest invokeAgentRequest,
        KernelArguments? arguments,
        [EnumeratorCancellation] CancellationToken cancellationToken)
    {
        // This session state is used to store the results of function calls to be passed back to the agent.
        // https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/BedrockAgentRuntime/TSessionState.html
        SessionState? sessionState = null;
        for (var requestIndex = 0; ; requestIndex++)
        {
            if (sessionState != null)
            {
                invokeAgentRequest.SessionState = sessionState;
                sessionState = null;
            }
            var invokeAgentResponse = await agent.RuntimeClient.InvokeAgentAsync(invokeAgentRequest, cancellationToken).ConfigureAwait(false);

            if (invokeAgentResponse.HttpStatusCode != System.Net.HttpStatusCode.OK)
            {
                throw new HttpOperationException($"Failed to invoke agent. Status code: {invokeAgentResponse.HttpStatusCode}");
            }

            List<FunctionCallContent> functionCallContents = [];
            foreach (var responseEvent in invokeAgentResponse.Completion)
            {
                if (responseEvent is BedrockAgentRuntimeEventStreamException bedrockAgentRuntimeEventStreamException)
                {
                    throw new KernelException("Failed to handle Bedrock Agent stream event.", bedrockAgentRuntimeEventStreamException);
                }

                var chatMessageContent =
                    HandleChunkEvent(agent, responseEvent) ??
                    HandleFilesEvent(agent, responseEvent) ??
                    HandleReturnControlEvent(agent, responseEvent, arguments) ??
                    HandleTraceEvent(agent, responseEvent) ??
                    throw new KernelException($"Failed to handle Bedrock Agent stream event: {responseEvent}");
                if (chatMessageContent.Items.Count > 0 && chatMessageContent.Items[0] is FunctionCallContent functionCallContent)
                {

View on GitHub (pinned to c028a0c7dc)

Solutions

  1. Map the HttpStatusCode: 401/403 → fix credentials/IAM; 404 → verify agentId and aliasId; 429 → retry with backoff; 5xx → transient, retry.
  2. Ensure the agent is in PREPARED status before invoking (use the status polling extension).
  3. Verify the agentId, aliasId, and region on the invoke request match a prepared agent.
  4. For 429/5xx, implement retry with exponential backoff and jitter.

Example fix

// before
try { await foreach (var r in agent.InvokeAsync(request, thread, cancellationToken)) { ... } }
catch (HttpOperationException ex) { logger.LogError(ex.Message); throw; }

// after — branch on status code
try { await foreach (var r in agent.InvokeAsync(request, thread, cancellationToken)) { ... } }
catch (HttpOperationException ex) when (ex.StatusCode == System.Net.HttpStatusCode.TooManyRequests) { await Task.Delay(backoff); /* retry */ }
catch (HttpOperationException ex) when (ex.StatusCode == System.Net.HttpStatusCode.NotFound) { logger.LogError("Agent or alias not found"); throw; }
Defensive patterns

Strategy: retry

Validate before calling

// Ensure agent is PREPARED before invoking
var a = await client.GetAgentAsync(new() { AgentId = agent.AgentId }, cancellationToken);
if (a.Agent.AgentStatus != AgentStatus.Prepared)
    throw new InvalidOperationException($"Agent not prepared (status={a.Agent.AgentStatus}).");

Try / catch

try { await foreach (var r in agent.InvokeAsync(request, thread, cancellationToken)) { ... } }
catch (HttpOperationException ex) when (ex.StatusCode == System.Net.HttpStatusCode.TooManyRequests) { await Task.Delay(backoff); /* retry */ }
catch (HttpOperationException ex) when ((int)ex.StatusCode >= 500) { await Task.Delay(backoff); /* retry transient */ }
catch (HttpOperationException ex) when (ex.StatusCode == System.Net.HttpStatusCode.NotFound) { logger.LogError("Agent/alias not found"); throw; }

Prevention

When it happens

Trigger: Invoking a Bedrock agent that is not in PREPARED status, using an expired or unauthorized session, referencing a non-existent agentId/aliasId, exceeding concurrency limits, or hitting a server-side error during invocation.

Common situations: Agent was created but never prepared (still DRAFT/NOT_PREPARED); wrong aliasId; credentials expired mid-session; throttled by Bedrock service quotas; regional mismatch between client and agent.

Related errors


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