microsoft/semantic-kernel · error · KernelException
Only one `Always` handler is allowed in a group of event han
Error message
Only one `Always` handler is allowed in a group of event handlers.
What it means
Thrown by DeclarativeEventHandlerGroupBuilder constructor when processing a condition of type Always. NOTE: The source code checks 'if (this.DefaultHandler is not null)' but throws the 'Always' message — this is likely a bug; the guard should check AlwaysHandler. In practice, the error fires when a Default handler was already set and an Always condition is subsequently encountered, or (if the bug is fixed) when two Always conditions exist.
Source
Thrown at dotnet/src/Experimental/Process.Core/ProcessAgentBuilder.cs:302
}
if (!string.IsNullOrWhiteSpace(condition.Expression))
{
throw new KernelException("`Default` handlers must not have an eval expression.");
}
this.DefaultHandler = new DeclarativeEventHandlerBuilder(condition);
}
else if (condition.Type == DeclarativeProcessConditionType.Eval)
{
this.EvalHandlers ??= [];
this.EvalHandlers.Add(new DeclarativeEventHandlerBuilder(condition));
}
else if (condition.Type == DeclarativeProcessConditionType.Always)
{
if (this.DefaultHandler is not null)
{
throw new KernelException("Only one `Always` handler is allowed in a group of event handlers.");
}
if (!string.IsNullOrWhiteSpace(condition.Expression))
{
throw new KernelException("`Always` handlers must not have an eval expression.");
}
this.AlwaysHandler = new DeclarativeEventHandlerBuilder(condition);
}
else
{
throw new KernelException($"Unknown condition type: {condition.Type}");
}
}
}
}
/// <summary>View on GitHub (pinned to c028a0c7dc)
Solutions
- Ensure at most one Always condition exists in the handler group and no conflicting Default handler has been registered before it.
- Reorder conditions so that Always comes before Default (workaround for the current DefaultHandler-guard behavior), or avoid mixing Default and Always in the same group until the guard bug is fixed.
- Report the guard bug upstream: the Always branch should check AlwaysHandler, not DefaultHandler.
Example fix
// before — Default registered first, then Always triggers the guard
var conditions = new List<DeclarativeProcessCondition>
{
new() { Type = DeclarativeProcessConditionType.Default },
new() { Type = DeclarativeProcessConditionType.Always } // throws due to guard checking DefaultHandler
};
// after — only one of Default or Always per group, or reorder so Always is first
var conditions = new List<DeclarativeProcessCondition>
{
new() { Type = DeclarativeProcessConditionType.Always }
}; Defensive patterns
Strategy: validation
Validate before calling
public static void ValidateAlwaysCondition(List<DeclarativeProcessCondition> conditions)
{
var alwaysCount = conditions.Count(c => c?.Type == DeclarativeProcessConditionType.Always);
if (alwaysCount > 1)
{
throw new KernelException("Only one Always handler is allowed per group.");
}
// Workaround for the current guard bug: avoid mixing Default and Always
var hasDefault = conditions.Any(c => c?.Type == DeclarativeProcessConditionType.Default);
var hasAlways = conditions.Any(c => c?.Type == DeclarativeProcessConditionType.Always);
if (hasDefault && hasAlways)
{
// Current implementation throws due to DefaultHandler check in Always branch.
throw new KernelException("Mixing Default and Always in one group triggers a known guard bug.");
}
} Prevention
- Keep at most one Always condition per handler group.
- Until the guard bug is fixed, avoid mixing Default and Always conditions in the same group, or place Always before Default in the list.
- Report the upstream bug: the Always branch should check AlwaysHandler, not DefaultHandler.
When it happens
Trigger: Passing a conditions list that includes at least one Always condition while a Default handler is already registered (due to the current guard checking DefaultHandler). If the guard is corrected to check AlwaysHandler, this would fire on duplicate Always conditions instead.
Common situations: Defining handler conditions in YAML or code that include both a Default and an Always condition in the same group. Including two Always conditions. The misleading guard makes this error appear in surprising situations where the user intended one Default + one Always, which should be valid.
Related errors
- Only one `Default` handler is allowed in a group of event ha
- `Default` handlers must not have an eval expression.
- `Always` handlers must not have an eval expression.
- Unknown condition type: {condition.Type}
- At least one action must be provided.
AI-assisted analysis of microsoft/semantic-kernel@c028a0c7dc (2026-08-13).
Data as JSON: /api/errors/7c9d0267b9dd3428.
Report an issue: GitHub.