Summary
VectorIndexPath, VectorIndexType, QuantizerType, and VectorIndexShardKey carry only Newtonsoft attributes ([JsonProperty], [JsonIgnore], [JsonConverter(typeof(StringEnumConverter))], [EnumMember(Value = "flat")], etc.). The SDK's internal write path for ContainerProperties is hard-routed through Newtonsoft via CosmosSerializerCore.IsInputTypeInternal, so this is correct for first-party use.
However, any customer code that re-serializes these public types with System.Text.Json — directly, or via a DTO mapped 1:1 onto our public shape — gets a wire body the service rejects:
[JsonIgnore] on the public IndexingSearchListSize is not honored by STJ → emits "IndexingSearchListSize": 0.
[JsonProperty(... NullValueHandling.Ignore)] on the private backing field is not seen → never emits "indexingSearchListSize" from the right source.
[JsonConverter(typeof(StringEnumConverter))] + [EnumMember(Value = "flat")] on Type is not honored → emits "Type": 0 instead of "flat".
[JsonProperty("path")] is not honored → emits "Path" (PascalCase).
This came up in an internal customer (Intune) repro where they round-trip indexing policies through their own STJ-serialized DTOs as part of a config-management pipeline. They've already worked around the enum casing with [EnumMember] on their own types but cannot work around the IndexingSearchListSize emission without changing every DTO property's type and ignore-condition.
Proposed change
Add parallel STJ attributes to the vector-index DOM types so they round-trip cleanly under either serializer. This is the same pattern adopted in PR #4618 for ChangeFeedItem / ChangeFeedMetadata:
// Example: VectorIndexPath.Type
[Newtonsoft.Json.JsonProperty(PropertyName = "type")]
[Newtonsoft.Json.JsonConverter(typeof(StringEnumConverter))]
[System.Text.Json.Serialization.JsonPropertyName("type")]
[System.Text.Json.Serialization.JsonConverter(typeof(EnumMemberStringEnumConverter<VectorIndexType>))]
public VectorIndexType Type { get; set; }
Scope:
VectorIndexPath — all properties (Path, Type, Dimensions, DistanceFunction, IndexingSearchListSize, QuantizationByteSize, VectorIndexShardKey)
VectorIndexType, QuantizerType, DistanceFunction — string-enum converter that honors [EnumMember]
VectorIndexShardKey
The public IndexingSearchListSize / QuantizationByteSize need [System.Text.Json.Serialization.JsonIgnore] so STJ doesn't double-emit them; the private backing fields need a matching [JsonPropertyName] + [JsonInclude] (or be promoted to internal-public bridges that STJ can see).
Tests to add
For each affected type, two repro fixtures:
- Serialize via Newtonsoft → assert exact wire shape (existing behavior unchanged).
- Serialize via STJ (default options + camelCase policy) → assert the same wire shape.
Why now
Customers are increasingly building config / IaC pipelines on top of System.Text.Json (AOT-friendly, no Newtonsoft dependency). The vector-index types are new enough that the inconsistency hasn't compounded yet — fixing it now is much cheaper than after broader adoption.
This is a focused subset of the broader STJ migration tracked across the AOT work; it doesn't require flipping the internal serializer, just publishing the dual attributes on the user-visible types.
Precedent
PR #4618 — ChangeFeedItem / ChangeFeedMetadata dual-attribute work, same pattern.
Summary
VectorIndexPath,VectorIndexType,QuantizerType, andVectorIndexShardKeycarry only Newtonsoft attributes ([JsonProperty],[JsonIgnore],[JsonConverter(typeof(StringEnumConverter))],[EnumMember(Value = "flat")], etc.). The SDK's internal write path forContainerPropertiesis hard-routed through Newtonsoft viaCosmosSerializerCore.IsInputTypeInternal, so this is correct for first-party use.However, any customer code that re-serializes these public types with
System.Text.Json— directly, or via a DTO mapped 1:1 onto our public shape — gets a wire body the service rejects:[JsonIgnore]on the publicIndexingSearchListSizeis not honored by STJ → emits"IndexingSearchListSize": 0.[JsonProperty(... NullValueHandling.Ignore)]on the private backing field is not seen → never emits"indexingSearchListSize"from the right source.[JsonConverter(typeof(StringEnumConverter))]+[EnumMember(Value = "flat")]onTypeis not honored → emits"Type": 0instead of"flat".[JsonProperty("path")]is not honored → emits"Path"(PascalCase).This came up in an internal customer (Intune) repro where they round-trip indexing policies through their own STJ-serialized DTOs as part of a config-management pipeline. They've already worked around the enum casing with
[EnumMember]on their own types but cannot work around theIndexingSearchListSizeemission without changing every DTO property's type and ignore-condition.Proposed change
Add parallel STJ attributes to the vector-index DOM types so they round-trip cleanly under either serializer. This is the same pattern adopted in PR #4618 for
ChangeFeedItem/ChangeFeedMetadata:Scope:
VectorIndexPath— all properties (Path,Type,Dimensions,DistanceFunction,IndexingSearchListSize,QuantizationByteSize,VectorIndexShardKey)VectorIndexType,QuantizerType,DistanceFunction— string-enum converter that honors[EnumMember]VectorIndexShardKeyThe public
IndexingSearchListSize/QuantizationByteSizeneed[System.Text.Json.Serialization.JsonIgnore]so STJ doesn't double-emit them; the private backing fields need a matching[JsonPropertyName]+[JsonInclude](or be promoted to internal-public bridges that STJ can see).Tests to add
For each affected type, two repro fixtures:
Why now
Customers are increasingly building config / IaC pipelines on top of
System.Text.Json(AOT-friendly, no Newtonsoft dependency). The vector-index types are new enough that the inconsistency hasn't compounded yet — fixing it now is much cheaper than after broader adoption.This is a focused subset of the broader STJ migration tracked across the AOT work; it doesn't require flipping the internal serializer, just publishing the dual attributes on the user-visible types.
Precedent
PR #4618 —
ChangeFeedItem/ChangeFeedMetadatadual-attribute work, same pattern.