Skip to content

.NET: ChatHistoryMemoryProvider swallows caller cancellation #8811

Closed

Description

@quifox

Description

ChatHistoryMemoryProvider treats vector search and history storage failures as best-effort, but its generic exception handlers also swallow OperationCanceledException when the caller-provided CancellationToken has been cancelled.

This affects both the BeforeAIInvoke search path and the post-invocation UpsertAsync storage path, allowing work to continue after caller cancellation.

Expected behavior

Caller-triggered cancellation should propagate. Unrelated provider-side failures, including provider-side cancellation when the caller token remains active, should keep the existing best-effort behavior.

Reproduction

With an already-cancelled caller token, configure SearchAsync or UpsertAsync to surface cancellation. Both paths currently complete without propagating OperationCanceledException.

The fix can remain narrow by filtering the generic catch based on whether the caller token is actually cancelled.

Activity

  1. added
    .NETUsage: [Issues, PRs], Target: .Net
    triageUsage: [Issues], Target: All issues that still need to be triaged
    on Sep 29, 2026
  2. added
    reproducedUsage: [Issues], Target: all issues that can be reproduced by the triage workflow
    on Sep 29, 2026
  3. github-actions commented on Sep 29, 2026

    @github-actions
    Contributor

    🤖 Automated triage reproduction notes (agent-authored — trust but verify)

    Agent analysis

    dotnet/src/Microsoft.Agents.AI/Memory/ChatHistoryMemoryProvider.cs::ProvideMessagesAsync and StoreAIContextAsync swallow caller-triggered cancellation in their generic exception handlers at lines 242 and 295. This occurs when an already-canceled caller token is passed and SearchAsync or UpsertAsync throws OperationCanceledException. Minimal repro: mock either vector-store operation to throw cancellation, invoke the provider with that cancelled token, and assert cancellation propagates.

    • Failing test: dotnet/tests/Microsoft.Agents.AI.UnitTests/Memory/ChatHistoryMemoryProviderTests.cs
    • Files examined: dotnet/src/Microsoft.Agents.AI/Memory/ChatHistoryMemoryProvider.cs, dotnet/tests/Microsoft.Agents.AI.UnitTests/Memory/ChatHistoryMemoryProviderTests.cs
    • Tests run: InvokedAsync_Throws_WhenCallerCancellationCausesUpsertCancellationAsync, MessageInvokingAsync_BeforeAInvoke_Throws_WhenCallerCancellationCausesSearchCancellationAsync, InvokedAsync_DoesNotThrow_WhenUpsertThrowsAsync
  4. added
    agentsUsage: [Issues, PRs], Target: Single agent
    and removed
    triageUsage: [Issues], Target: All issues that still need to be triaged
    on Sep 29, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

.NETUsage: [Issues, PRs], Target: .NetagentsUsage: [Issues, PRs], Target: Single agentreproducedUsage: [Issues], Target: all issues that can be reproduced by the triage workflow

Type

Projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions