microsoft/semantic-kernel · error · KernelException

Agent Failure - Run not created for thread: ${threadId}

Error message

Agent Failure - Run not created for thread: ${threadId}

What it means

Thrown in the streaming InvokeStreamingAsync path when, after polling, the local 'run' variable is still null - meaning the run was never successfully created/returned by the service. Note a formatting bug: the message uses "${threadId}" which in C# emits a literal '$' before the interpolated threadId value, so the displayed threadId is still present but prefixed with '$'. This is a service-side run-creation failure.

Source

Thrown at dotnet/src/Agents/AzureAI/Internal/AgentThreadActions.cs:459

                    switch (stepUpdate.UpdateKind)
                    {
                        case StreamingUpdateReason.RunStepCompleted when stepUpdate.Value.StepDetails is RunStepToolCallDetails toolDetails:
                            ProcessToolCallStep(stepUpdate.Value, toolDetails, agent, messages, threadId, stepFunctionResults);
                            break;

                        case StreamingUpdateReason.RunStepCompleted when stepUpdate.Value.StepDetails is RunStepMessageCreationDetails:
                            messageCreationStepsToProcess.Add(stepUpdate.Value);
                            break;

                        default:
                            break;
                    }
                }
            }

            if (run == null)
            {
                throw new KernelException($"Agent Failure - Run not created for thread: ${threadId}");
            }

            // Is in terminal state?
            if (s_failureStatuses.Contains(run.Status))
            {
                throw new KernelException($"Agent Failure - Run terminated: {run.Status} [{run.Id}]: {run.LastError?.Message ?? "Unknown"}");
            }

            if (run.Status == RunStatus.RequiresAction)
            {
                List<RunStep> activeSteps = [];
                await foreach (var step in client.GetStepsAsync(run, cancellationToken).ConfigureAwait(false))
                {
                    if (step.Status == RunStepStatus.InProgress)
                    {
                        activeSteps.Add(step);
                    }
                }

View on GitHub (pinned to c028a0c7dc)

Solutions

  1. Treat as transient: retry the streaming invocation with exponential backoff.
  2. Verify credentials (TokenCredential) and that the assistant/agent Id is valid.
  3. Check Azure service health and throttling headers.
  4. Capture the threadId from your call context (the exception text shows it after the '$') for support correlation.
Defensive patterns

Strategy: retry

Try / catch

try { await foreach (var m in agent.InvokeStreamingAsync(messages, thread, ct)) { /*...*/ } }
catch (KernelException ex) when (ex.Message.Contains("Run not created"))
{
    // run creation failed; retry with backoff, verify credentials/assistant id
    logger.LogWarning("Streaming run not created: {Msg}", ex.Message);
}

Prevention

When it happens

Trigger: Streaming invoke where the polling loop completes without ever assigning a non-null run object - typically the createRun API call failed or returned nothing usable before the loop checked run == null.

Common situations: Transient Azure AI service outage during run creation; authentication/authorization failure preventing run creation; throttling at creation time; SDK version mismatch causing a deserialization gap.

Related errors


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