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
- Treat as transient: retry the streaming invocation with exponential backoff.
- Verify credentials (TokenCredential) and that the assistant/agent Id is valid.
- Check Azure service health and throttling headers.
- 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
- Verify TokenCredential and assistant/agent Id before streaming.
- Wrap streaming calls in retry logic for run-creation failures.
- Fall back to non-streaming invocation if streaming run creation repeatedly fails.
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
- Agent Failure - Run terminated: {run.Status} [{run.Id}]: {ru
- Failed to search the collection.
- Agent Failure - Run not created for thread: ${threadId}
- Response failed
- {type(agent)} service failed to complete the request
AI-assisted analysis of microsoft/semantic-kernel@c028a0c7dc (2026-08-13).
Data as JSON: /api/errors/906241ba9687d27d.
Report an issue: GitHub.