microsoft/semantic-kernel · warning · OperationCanceledException
Delivery of message {messageId} was cancelled.
Error message
Delivery of message {messageId} was cancelled. What it means
InProcessRuntime.SendMessageAsync awaits the delivery's ResultSink.Future; if it faults with TargetInvocationException wrapping OperationCanceledException, the catch unwraps and rethrows a new OperationCanceledException naming the messageId. This is the normal propagation when a message delivery is cancelled (explicit token, agent-side cancellation, or runtime shutdown).
Source
Thrown at dotnet/src/Agents/Runtime/InProcess/InProcessRuntime.cs:142
public async ValueTask<object?> SendMessageAsync(object message, AgentId recipient, AgentId? sender = null, string? messageId = null, CancellationToken cancellationToken = default)
{
return await this.ExecuteTracedAsync(async () =>
{
MessageDelivery delivery =
new MessageEnvelope(message, messageId, cancellationToken)
.WithSender(sender)
.ForSend(recipient, this.SendMessageServicerAsync);
this._messageDeliveryQueue.Enqueue(delivery);
Interlocked.Increment(ref this.messageQueueCount);
try
{
return await delivery.ResultSink.Future.ConfigureAwait(false);
}
catch (TargetInvocationException ex) when (ex.InnerException is OperationCanceledException innerOCEx)
{
throw new OperationCanceledException($"Delivery of message {messageId} was cancelled.", innerOCEx);
}
}).ConfigureAwait(false);
}
/// <inheritdoc/>
public async ValueTask<AgentId> GetAgentAsync(AgentId agentId, bool lazy = true)
{
if (!lazy)
{
await this.EnsureAgentAsync(agentId).ConfigureAwait(false);
}
return agentId;
}
/// <inheritdoc/>
public ValueTask<AgentId> GetAgentAsync(AgentType agentType, string key = AgentId.DefaultKey, bool lazy = true)
=> this.GetAgentAsync(new AgentId(agentType, key), lazy);View on GitHub (pinned to c028a0c7dc)
Solutions
- If cancellation is expected, catch OperationCanceledException and treat it as non-fatal.
- Ensure your CancellationToken is not cancelled prematurely (check timeout/CancellationTokenSource configuration).
- Avoid calling StopAsync while RPC sends are still awaited if you need their results.
Example fix
// before
object? reply = await runtime.SendMessageAsync(msg, recipient, cancellationToken: cts.Token);
// after
try
{
object? reply = await runtime.SendMessageAsync(msg, recipient, cancellationToken: cts.Token);
}
catch (OperationCanceledException) when (cts.IsCancellationRequested)
{
// expected cancellation; handle gracefully
} Defensive patterns
Strategy: try-catch
Try / catch
try { object? reply = await runtime.SendMessageAsync(msg, recipient, cancellationToken: ct); }
catch (OperationCanceledException) when (ct.IsCancellationRequested)
{
// expected cancellation; do not treat as fatal
} Prevention
- Do not cancel the token if you still need the send's result.
- Avoid StopAsync while RPC sends are in flight.
- Distinguish expected cancellation (timeouts) from unexpected agent-side cancellation.
When it happens
Trigger: The caller's CancellationToken passed to SendMessageAsync is cancelled mid-delivery; the runtime's shutdown token (_shutdownSource) cancels pending deliveries; the receiving agent throws OperationCanceledException; StopAsync fires while an RPC send is in flight.
Common situations: Request timeouts implemented via CancellationTokenSource.CancelAfter; user-initiated cancel; graceful shutdown that aborts in-flight sends; an agent whose handler honors cancellation.
Related errors
- Message must have a receiver to be sent.
- Message must have a topic to be published.
- Runtime is already running.
- Runtime is already stopping.
- Agent with name {agentId.Type} is not of type {typeof(TAgent
AI-assisted analysis of microsoft/semantic-kernel@c028a0c7dc (2026-08-13).
Data as JSON: /api/errors/9ea19d1e5d3bfad9.
Report an issue: GitHub.