Skip to content

[Preview] Container: Fixes SemanticRerankAsync TypeLoadException in derived classes#5783

Merged
kirankumarkolli merged 4 commits intomasterfrom
users/ntripician/fix-semantic-rerank-typeload
Apr 21, 2026
Merged

[Preview] Container: Fixes SemanticRerankAsync TypeLoadException in derived classes#5783
kirankumarkolli merged 4 commits intomasterfrom
users/ntripician/fix-semantic-rerank-typeload

Conversation

@NaluTripician
Copy link
Copy Markdown
Contributor

Problem

System.TypeLoadException: Method SemanticRerankAsync in type Microsoft.Azure.Cosmos.Encryption.Custom.EncryptionContainer does not have an implementation.

Root Cause

SemanticRerankAsync was declared as abstract in the Container base class (under #if PREVIEW). Derived classes like EncryptionContainer in the Encryption.Custom project only override this method when both PREVIEW && SDKPROJECTREF preprocessor symbols are defined. When PREVIEW is not defined in the consuming project but the NuGet preview package includes the abstract method, the derived class is missing the required implementation, causing a TypeLoadException at runtime.

Fix

Changed SemanticRerankAsync from abstract to virtual with a default implementation that throws NotImplementedException. This follows the existing pattern used by other methods in Container (e.g., DeleteAllItemsByPartitionKeyStreamAsync) and prevents the TypeLoadException in derived classes that don't override the method.

@azure-pipelines
Copy link
Copy Markdown

Azure Pipelines:
Successfully started running 1 pipeline(s).

…sses

Change SemanticRerankAsync from abstract to virtual with a default
NotImplementedException throw. This prevents TypeLoadException in
derived classes like EncryptionContainer that may not compile with
the PREVIEW preprocessor flag enabled, yet reference a preview
NuGet package that includes the abstract method.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@NaluTripician NaluTripician force-pushed the users/ntripician/fix-semantic-rerank-typeload branch from 42e6a5b to 6ee580c Compare April 14, 2026 19:59
@azure-pipelines
Copy link
Copy Markdown

Azure Pipelines:
Successfully started running 1 pipeline(s).

@kirankumarkolli
Copy link
Copy Markdown
Member

@juraj-blazek FYI

…-virtual change

Update DotNetPreviewSDKAPI.net6.json to reflect IsAbstract:False for
SemanticRerankAsync after changing from abstract to virtual in Container.cs.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@azure-pipelines
Copy link
Copy Markdown

Azure Pipelines:
Successfully started running 1 pipeline(s).

@azure-pipelines
Copy link
Copy Markdown

Azure Pipelines:
Successfully started running 1 pipeline(s).

@azure-pipelines
Copy link
Copy Markdown

Azure Pipelines:
Successfully started running 1 pipeline(s).

@kirankumarkolli kirankumarkolli merged commit d4c91a0 into master Apr 21, 2026
30 of 32 checks passed
@kirankumarkolli kirankumarkolli deleted the users/ntripician/fix-semantic-rerank-typeload branch April 21, 2026 19:30
@NaluTripician NaluTripician changed the title Container: Fixes SemanticRerankAsync TypeLoadException in derived classes [Preview] Container: Fixes SemanticRerankAsync TypeLoadException in derived classes Apr 21, 2026
NaluTripician added a commit that referenced this pull request Apr 21, 2026
… gaps

The Encryption and Encryption.Custom official release pipelines previously

built each project only against the pinned Microsoft.Azure.Cosmos NuGet.

That does not detect abstract members added to Container on master that lack

an unconditional override in EncryptionContainer - the exact class of defect

fixed by PR #5783 (SemanticRerankAsync TypeLoadException).

The override for the fixed method was gated '#if PREVIEW && SDKPROJECTREF',

so a build that defines both symbols (the existing PR validation pattern)

also masks the defect: the override is compiled back in and the missing-

implementation condition never manifests. The bug only surfaces when the

Encryption.Custom NuGet is built with PREVIEW on and SDKPROJECTREF off and

is then loaded against an SDK that contains the new abstract member.

This change:

1. Decouples the SDKPROJECTREF preprocessor define from the SdkProjectRef

   MSBuild property via a new DefineSdkProjectRefSymbol knob. Default

   behavior is unchanged: SdkProjectRef=true still sets SDKPROJECTREF.

2. Adds two build steps to each encryption official release-gate template:

   - SDKREF build: '-p:IsPreview=true -p:SdkProjectRef=true' - verifies the

     full project-reference path still compiles against master SDK source.

   - NuGet-surface parity build: '-p:IsPreview=true -p:SdkProjectRef=true

     -p:DefineSdkProjectRefSymbol=false' - links against master SDK source

     with the exact preprocessor surface of the shipped NuGet (PREVIEW on,

     SDKPROJECTREF off). Any newly-added abstract member on Container that

     lacks an unconditional override in EncryptionContainer now fails this

     step with CS0534.

Verified locally by reverting PR #5783 in a worktree: the parity build for

Encryption.Custom fails with CS0534 on SemanticRerankAsync, exactly catching

the bug. All six build permutations (default + SDKREF + parity for both

Encryption and Encryption.Custom) pass at the fixed state.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
NaluTripician added a commit that referenced this pull request Apr 23, 2026
Re-introduces the SemanticRerankAsync abstract declaration so the new
NuGet-surface parity build in this PR should fail with CS0534 on the
Encryption.Custom project. Will be reverted once pipeline failure is confirmed.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
microsoft-github-policy-service Bot pushed a commit that referenced this pull request Apr 24, 2026
… gaps (#5798)

## Problem

The Encryption and Encryption.Custom official release pipelines
previously built each project only against the pinned
`Microsoft.Azure.Cosmos` NuGet declared in the project file. That does
not detect abstract members added to `Container` on master that lack an
unconditional override in `EncryptionContainer` — the exact class of
defect fixed by #5783 (`SemanticRerankAsync` `TypeLoadException`).

The customer-facing symptom from #5783:

> `System.TypeLoadException`: Method `SemanticRerankAsync` in type
`Microsoft.Azure.Cosmos.Encryption.Custom.EncryptionContainer` does not
have an implementation.

## Why a naive SDKREF build is not enough

The override was gated `#if PREVIEW && SDKPROJECTREF`. Any build that
defines **both** symbols — which is what the existing PR-validation
build (`build-preview.yml`) does, and what an obvious "build with
`SdkProjectRef=true`" addition would also do — compiles the override
back in and the missing-implementation condition never manifests:

| Build mode | `PREVIEW` | `SDKPROJECTREF` | Override present? | Catches
the bug? |
|---|---|---|---|---|
| Current default (NuGet ref, pinned `3.41.0-preview.0`) | ❌ | ❌ | — (no
abstract either) | ❌ |
| `-p:IsPreview=true -p:SdkProjectRef=true` | ✅ | ✅ | ✅ | ❌ (masks the
defect) |
| **New parity build** (`DefineSdkProjectRefSymbol=false`) | ✅ | ❌ | ❌ |
✅ |

The bug only manifests when `PREVIEW` is on and `SDKPROJECTREF` is off,
linked against an SDK that contains the new abstract member. That is the
exact surface of the shipped Encryption.Custom NuGet.

## Change

1. **Decouple the `SDKPROJECTREF` preprocessor define from the
`SdkProjectRef` MSBuild property** via a new `DefineSdkProjectRefSymbol`
knob in both:
-
`Microsoft.Azure.Cosmos.Encryption.Custom/src/Microsoft.Azure.Cosmos.Encryption.Custom.csproj`
-
`Microsoft.Azure.Cosmos.Encryption/src/Microsoft.Azure.Cosmos.Encryption.csproj`

Default behaviour is unchanged: `SdkProjectRef=true` still sets
`SDKPROJECTREF`. Pipelines can now opt out with
`-p:DefineSdkProjectRefSymbol=false`.

2. **Add two build steps** to each encryption official release-gate
template (`templates/static-tools-encryption.yml`,
`templates/static-tools-encryption-custom.yml`):

- **SDKREF build** — `-p:IsPreview=true -p:SdkProjectRef=true`. Verifies
the full project-reference path still compiles against master SDK
source.
- **NuGet-surface parity build** — `-p:IsPreview=true
-p:SdkProjectRef=true -p:DefineSdkProjectRefSymbol=false`. Links against
master SDK source with the exact preprocessor surface of the shipped
NuGet. Any newly-added abstract member on `Container` under `#if
PREVIEW` without an unconditional override in `EncryptionContainer` now
fails this step with `CS0534`.

## Proof the pipeline catches #5783

I reverted #5783 in a worktree (`virtual` → `abstract` on
`Container.SemanticRerankAsync`) and ran the new parity build for
Encryption.Custom:

```
error CS0534: 'EncryptionContainer' does not implement inherited abstract
member 'Container.SemanticRerankAsync(string, IEnumerable<string>,
IDictionary<string, object>, CancellationToken)'
Build FAILED.
```

That is exactly the runtime `TypeLoadException` surface from the
customer report, caught at compile time.

All six build permutations (default / SDKREF / parity × Encryption /
Encryption.Custom) pass at the fixed state:

| Project | Default (NuGet) | SDKREF | NuGet-surface parity |
|---|---|---|---|
| `Microsoft.Azure.Cosmos.Encryption` | ✅ | ✅ | ✅ |
| `Microsoft.Azure.Cosmos.Encryption.Custom` | ✅ | ✅ | ✅ |

## Type of change

- [x] Bug fix (non-breaking change which fixes an issue)
- [ ] New feature (non-breaking change which adds functionality)
- [ ] Breaking change (fix or feature that would cause existing
functionality to not work as expected)
- [ ] This change requires a documentation update

## Closing issues

Related to #5783.

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Debdatta Kunda <87335885+kundadebdatta@users.noreply.github.com>
@NaluTripician NaluTripician mentioned this pull request Apr 24, 2026
4 tasks
microsoft-github-policy-service Bot pushed a commit that referenced this pull request Apr 25, 2026
## Release 3.59.0

### Version Changes
- ClientOfficialVersion: 3.58.0 → 3.59.0
- ClientPreviewVersion: 3.59.0 → 3.60.0
- ClientPreviewSuffixVersion: preview.0 → preview.0

### Changelog (3.59.0 GA)

#### Added
- [5579](#5579)
Change Feed Processor: Adds Lease container export support
- [5709](#5709)
Performance: Adds caching for URL-encoded AAD authorization signature
- [5731](#5731) DNS
dot-suffix: Adds TCP DNS dot-suffix for Direct mode to avoid Kubernetes
ndots latency
- [5755](#5755)
Exceptionless: Adds enabling exception less 400 status code
- [5756](#5756)
Exceptionless: Adds enabling exception less 404/1002 status code
- [5757](#5757)
Exceptionless: Adds enabling exception less 403
- [5779](#5779)
Direct: Adds Direct package version bump to 3.42.4
- [5786](#5786)
Region Availability: Adds missing regions from Direct 3.42.4
- [5788](#5788)
Socket Handler: Adds HTTP/2 PING keep-alive to detect broken connections
in pool

#### Fixed
- [5553](#5553)
NativeDLLs: Fixes Conditionally include win-x64 native DLLs based on
RuntimeIdentifier
- [5588](#5588)
LINQ: Fixes memory leak from Expression.Compile() in all call sites
- [5617](#5617)
ChangeFeedProcessor: Fixes first-change skip during initial startup by
anchoring StartTime
- [5636](#5636)
CosmosClientBuilder: Fixes self-referencing loop in
GetSerializedConfiguration with STJ TypeInfoResolver
- [5748](#5748)
Routing: Fixes GetOverlappingRanges CPU overhead from repeated JSON
deserialization
- [5807](#5807)
ChangeFeedProcessor: Fixes lease de-duplication for
/partitionKey-partitioned lease containers

### Changelog (3.60.0-preview.0)

#### Added
- [5804](#5804)
SemanticReranking: Adds Configurable Request Timeout

#### Fixed
- [5783](#5783)
Container: Fixes SemanticRerankAsync TypeLoadException in derived
classes

### API Contract Diff (GA)
```diff
diff --git "a/Microsoft.Azure.Cosmos\\contracts\\API_3.58.0.txt" "b/Microsoft.Azure.Cosmos\\contracts\\API_3.59.0.txt"
index 1b74a69..6fa9352 100644
--- "a/Microsoft.Azure.Cosmos\\contracts\\API_3.58.0.txt"
+++ "b/Microsoft.Azure.Cosmos\\contracts\\API_3.59.0.txt"
@@ -60,6 +60,7 @@ namespace Microsoft.Azure.Cosmos
         public ChangeFeedProcessor Build();
         public ChangeFeedProcessorBuilder WithErrorNotification(Container.ChangeFeedMonitorErrorDelegate errorDelegate);
         public virtual ChangeFeedProcessorBuilder WithInMemoryLeaseContainer();
+        public virtual ChangeFeedProcessorBuilder WithInMemoryLeaseContainer(MemoryStream leaseState);
         public ChangeFeedProcessorBuilder WithInstanceName(string instanceName);
         public ChangeFeedProcessorBuilder WithLeaseAcquireNotification(Container.ChangeFeedMonitorLeaseAcquireDelegate acquireDelegate);
         public ChangeFeedProcessorBuilder WithLeaseConfiguration(Nullable<TimeSpan> acquireInterval=default(Nullable<TimeSpan>), Nullable<TimeSpan> expirationInterval=default(Nullable<TimeSpan>), Nullable<TimeSpan> renewInterval=default(Nullable<TimeSpan>));
@@ -956,6 +957,7 @@ namespace Microsoft.Azure.Cosmos
         public const string NorwayWest = "Norway West";
         public const string PolandCentral = "Poland Central";
         public const string QatarCentral = "Qatar Central";
+        public const string SaudiArabiaEast = "Saudi Arabia East";
         public const string SingaporeCentral = "Singapore Central";
         public const string SingaporeNorth = "Singapore North";
         public const string SouthAfricaNorth = "South Africa North";
@@ -963,6 +965,7 @@ namespace Microsoft.Azure.Cosmos
         public const string SouthCentralUS = "South Central US";
         public const string SouthCentralUS2 = "South Central US 2";
         public const string SoutheastAsia = "Southeast Asia";
+        public const string SoutheastAsia3 = "Southeast Asia 3";
         public const string SoutheastUS = "Southeast US";
         public const string SoutheastUS3 = "Southeast US 3";
         public const string SoutheastUS5 = "Southeast US 5";
@@ -990,6 +993,7 @@ namespace Microsoft.Azure.Cosmos
         public const string USSecWest = "USSec West";
         public const string USSecWestCentral = "USSec West Central";
         public const string WestCentralUS = "West Central US";
+        public const string WestCentralUSFRE = "West Central US FRE";
         public const string WestEurope = "West Europe";
         public const string WestIndia = "West India";
         public const string WestUS = "West US";

```

### API Contract Diff (Preview)
```diff
diff --git "a/Microsoft.Azure.Cosmos\\contracts\\API_3.59.0-preview.0.txt" "b/Microsoft.Azure.Cosmos\\contracts\\API_3.60.0-preview.0.txt"
index 1ae52c0..58df10f 100644
--- "a/Microsoft.Azure.Cosmos\\contracts\\API_3.59.0-preview.0.txt"
+++ "b/Microsoft.Azure.Cosmos\\contracts\\API_3.60.0-preview.0.txt"
@@ -91,6 +91,7 @@ namespace Microsoft.Azure.Cosmos
         public ChangeFeedProcessor Build();
         public ChangeFeedProcessorBuilder WithErrorNotification(Container.ChangeFeedMonitorErrorDelegate errorDelegate);
         public virtual ChangeFeedProcessorBuilder WithInMemoryLeaseContainer();
+        public virtual ChangeFeedProcessorBuilder WithInMemoryLeaseContainer(MemoryStream leaseState);
         public ChangeFeedProcessorBuilder WithInstanceName(string instanceName);
         public ChangeFeedProcessorBuilder WithLeaseAcquireNotification(Container.ChangeFeedMonitorLeaseAcquireDelegate acquireDelegate);
         public ChangeFeedProcessorBuilder WithLeaseConfiguration(Nullable<TimeSpan> acquireInterval=default(Nullable<TimeSpan>), Nullable<TimeSpan> expirationInterval=default(Nullable<TimeSpan>), Nullable<TimeSpan> renewInterval=default(Nullable<TimeSpan>));
@@ -302,7 +303,7 @@ namespace Microsoft.Azure.Cosmos
         public abstract Task<ResponseMessage> ReplaceItemStreamAsync(Stream streamPayload, string id, PartitionKey partitionKey, ItemRequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken));
         public abstract Task<ThroughputResponse> ReplaceThroughputAsync(ThroughputProperties throughputProperties, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken));
         public abstract Task<ThroughputResponse> ReplaceThroughputAsync(int throughput, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken));
-        public abstract Task<SemanticRerankResult> SemanticRerankAsync(string rerankContext, IEnumerable<string> documents, IDictionary<string, object> options=null, CancellationToken cancellationToken=default(CancellationToken));
+        public virtual Task<SemanticRerankResult> SemanticRerankAsync(string rerankContext, IEnumerable<string> documents, IDictionary<string, object> options=null, CancellationToken cancellationToken=default(CancellationToken));
         public abstract Task<ItemResponse<T>> UpsertItemAsync<T>(T item, Nullable<PartitionKey> partitionKey=default(Nullable<PartitionKey>), ItemRequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken));
         public abstract Task<ResponseMessage> UpsertItemStreamAsync(Stream streamPayload, PartitionKey partitionKey, ItemRequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken));
         public delegate Task ChangeFeedHandlerWithManualCheckpoint<T>(ChangeFeedProcessorContext context, IReadOnlyCollection<T> changes, Func<Task> checkpointAsync, CancellationToken cancellationToken);
@@ -407,6 +408,7 @@ namespace Microsoft.Azure.Cosmos
         public int GatewayModeMaxConnectionLimit { get; set; }
         public Func<HttpClient> HttpClientFactory { get; set; }
         public Nullable<TimeSpan> IdleTcpConnectionTimeout { get; set; }
+        public TimeSpan InferenceRequestTimeout { get; set; }
         public bool LimitToEndpoint { get; set; }
         public Nullable<int> MaxRequestsPerTcpConnection { get; set; }
         public Nullable<int> MaxRetryAttemptsOnRateLimitedRequests { get; set; }
@@ -1092,6 +1094,7 @@ namespace Microsoft.Azure.Cosmos
         public const string NorwayWest = "Norway West";
         public const string PolandCentral = "Poland Central";
         public const string QatarCentral = "Qatar Central";
+        public const string SaudiArabiaEast = "Saudi Arabia East";
         public const string SingaporeCentral = "Singapore Central";
         public const string SingaporeNorth = "Singapore North";
         public const string SouthAfricaNorth = "South Africa North";
@@ -1099,6 +1102,7 @@ namespace Microsoft.Azure.Cosmos
         public const string SouthCentralUS = "South Central US";
         public const string SouthCentralUS2 = "South Central US 2";
         public const string SoutheastAsia = "Southeast Asia";
+        public const string SoutheastAsia3 = "Southeast Asia 3";
         public const string SoutheastUS = "Southeast US";
         public const string SoutheastUS3 = "Southeast US 3";
         public const string SoutheastUS5 = "Southeast US 5";
@@ -1126,6 +1130,7 @@ namespace Microsoft.Azure.Cosmos
         public const string USSecWest = "USSec West";
         public const string USSecWestCentral = "USSec West Central";
         public const string WestCentralUS = "West Central US";
+        public const string WestCentralUSFRE = "West Central US FRE";
         public const string WestEurope = "West Europe";
         public const string WestIndia = "West India";
         public const string WestUS = "West US";
@@ -1504,6 +1509,7 @@ namespace Microsoft.Azure.Cosmos.Fluent
         public CosmosClientBuilder WithEnableRemoteRegionPreferredForSessionRetry(bool enableRemoteRegionPreferredForSessionRetry);
         public CosmosClientBuilder WithFaultInjection(IFaultInjector faultInjector);
         public CosmosClientBuilder WithHttpClientFactory(Func<HttpClient> httpClientFactory);
+        public CosmosClientBuilder WithInferenceRequestTimeout(TimeSpan inferenceRequestTimeout);
         public CosmosClientBuilder WithLimitToEndpoint(bool limitToEndpoint);
         public CosmosClientBuilder WithPriorityLevel(PriorityLevel priorityLevel);
         public CosmosClientBuilder WithReadConsistencyStrategy(ReadConsistencyStrategy readConsistencyStrategy);

```

### Checklist
- [ ] Changelog entries reviewed by team
- [ ] API contract diff reviewed by Kiran and Kirill
- [ ] Preview APIs reviewed (email sent to
azurecosmossdkdotnet@microsoft.com)
- [ ] Kiran sign-off obtained

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants