microsoft/semantic-kernel · error · KernelException
Failed to complete step {stepId} for session {sessionId}.
Error message
Failed to complete step {stepId} for session {sessionId}. What it means
FlowExecutor runs a ReAct-style loop for up to _config.MaxStepIterations. Each iteration asks the model to produce a thought + action, executes the action, and checks whether the step's Provides variables are satisfied. If the loop exhausts all iterations without the step completing (no final answer and all provides populated), KernelException is thrown. This is a timeout-equivalent for a step that never converged.
Source
Thrown at dotnet/src/Experimental/Orchestration.Flow/Execution/FlowExecutor.cs:789
continue;
}
this._logger?.LogWarning("Action: No result from action");
}
else
{
actionStep.Observation = "ACTION $JSON_BLOB must be provided as part of thought process.";
this._logger?.LogWarning("Action: No action to take");
}
if (this._config.MinIterationTimeMs > 0)
{
// continue to next iteration
await Task.Delay(this._config.MinIterationTimeMs).ConfigureAwait(false);
}
}
throw new KernelException($"Failed to complete step {stepId} for session {sessionId}.");
}
private sealed class RepeatOrStartStepResult(bool? execute, string? prompt = null)
{
public bool? Execute { get; } = execute;
public string? Prompt { get; } = prompt;
}
}
View on GitHub (pinned to c028a0c7dc)
Solutions
- Increase _config.MaxStepIterations to give the step more reasoning rounds.
- Inspect the saved ReAct steps (via the flow status provider) to see what the model produced each iteration — look for malformed actions or empty results.
- Improve the step's prompt/instructions so the model produces well-formed ACTION JSON.
- Verify the action functions/plugins return non-empty results that populate the step's Provides variables.
- Use a more capable model if the current one consistently fails the ReAct format.
- Reduce MinIterationTimeMs if it is inflating wall-clock without adding value.
Example fix
// before — default iteration count too low for complex step
var config = new FlowConfig { MaxStepIterations = 3, MinIterationTimeMs = 1000 };
// after — more iterations, less delay
var config = new FlowConfig { MaxStepIterations = 10, MinIterationTimeMs = 0 }; Defensive patterns
Strategy: try-catch
Validate before calling
// Pre-call: ensure config has enough iterations for complex steps
if (config.MaxStepIterations < 5)
{
logger.LogWarning("MaxStepIterations is low ({N}); complex steps may fail to converge.", config.MaxStepIterations);
} Try / catch
try { await executor.ExecuteAsync(sessionId, flow, arguments); }
catch (KernelException ex) when (ex.Message.Contains("Failed to complete step"))
{
// Inspect saved ReAct steps to diagnose why the step didn't converge
var steps = await statusProvider.GetReActStepsAsync(sessionId, stepId);
logger.LogWarning("Step did not converge after {Count} iterations. Last thought: {Thought}",
steps.Count, steps.LastOrDefault()?.Thought);
throw;
} Prevention
- Set MaxStepIterations generously (e.g. 10+) for complex multi-action steps.
- Monitor ReAct step logs to detect models that struggle with the action format.
- Ensure action plugins return non-empty results that populate all step.Provides variables.
- Use a capable model that reliably follows the ReAct prompt format.
When it happens
Trigger: The model repeatedly fails to produce a valid ACTION JSON blob (falling into the 'ACTION $JSON_BLOB must be provided' branch), or produces actions whose results never populate all of step.Provides, or never emits a FinalAnswer. The loop runs MaxStepIterations times and gives up.
Common situations: Weak or misconfigured model that struggles with the ReAct prompt format. MaxStepIterations set too low for a complex step. The action plugin returns empty results, so provides are never satisfied. A content filter or token limit truncates the model output so the action parse fails every time.
Related errors
- Step {step.Goal} requires arguments {string.Join(",", step.R
- Failed to deserialize execution state for sessionId={session
- Failed to parse response: {responseText}
- {nameof(A2AAgent)} is not for use with {nameof(AgentChat)}.
- Missing agent description: {agent.Name ?? agent.Id}
AI-assisted analysis of microsoft/semantic-kernel@c028a0c7dc (2026-08-13).
Data as JSON: /api/errors/fd13042ab56dc735.
Report an issue: GitHub.