dotnet/efcore · error · InvalidOperationException
The requested configuration is not stored in the read-optimi
Error message
The requested configuration is not stored in the read-optimized model, please use 'DbContext.GetService<IDesignTimeModel>().Model'.
What it means
GetVectorIndexType() reads the Cosmos vector-index-type annotation from an index. The read-optimized runtime model (RuntimeIndex) deliberately omits design-time-only annotations to stay lean, so calling it on a RuntimeIndex throws InvalidOperationException via CoreStrings.RuntimeModelMissingData and directs you to the design-time model instead. Use DbContext.GetService<IDesignTimeModel>().Model for any annotation/configuration-source inspection.
Source
Thrown at src/EFCore.Cosmos/Extensions/CosmosIndexExtensions.cs:26
/// <summary>
/// Index extension methods for Azure Cosmos DB-specific metadata.
/// </summary>
/// <remarks>
/// See <see href="https://aka.ms/efcore-docs-modeling">Modeling entity types and relationships</see>, and
/// <see href="https://aka.ms/efcore-docs-cosmos">Accessing Azure Cosmos DB with EF Core</see> for more information and examples.
/// </remarks>
public static class CosmosIndexExtensions
{
/// <summary>
/// Returns the vector index type to use, such as "flat", "diskANN", or "quantizedFlat".
/// See <see href="https://aka.ms/ef-cosmos-vectors">Vector Search in Azure Cosmos DB for NoSQL</see> for more information.
/// </summary>
/// <param name="index">The index.</param>
/// <returns>The index type to use, or <see langword="null" /> if none is set.</returns>
public static VectorIndexType? GetVectorIndexType(this IReadOnlyIndex index)
=> (index is RuntimeIndex)
? throw new InvalidOperationException(CoreStrings.RuntimeModelMissingData)
: (VectorIndexType?)index[CosmosAnnotationNames.VectorIndexType];
/// <summary>
/// Sets the vector index type to use, such as "flat", "diskANN", or "quantizedFlat".
/// See <see href="https://aka.ms/ef-cosmos-vectors">Vector Search in Azure Cosmos DB for NoSQL</see> for more information.
/// </summary>
/// <param name="index">The index.</param>
/// <param name="indexType">The index type to use.</param>
public static void SetVectorIndexType(this IMutableIndex index, VectorIndexType? indexType)
=> index.SetOrRemoveAnnotation(CosmosAnnotationNames.VectorIndexType, indexType);
/// <summary>
/// Sets the vector index type to use, such as "flat", "diskANN", or "quantizedFlat".
/// See <see href="https://aka.ms/ef-cosmos-vectors">Vector Search in Azure Cosmos DB for NoSQL</see> for more information.
/// </summary>
/// <param name="index">The index.</param>
/// <param name="indexType">The index type to use.</param>
/// <param name="fromDataAnnotation">Indicates whether the configuration was specified using a data annotation.</param>View on GitHub (pinned to dbf9771522)
Solutions
- Obtain the index from the design-time model: var dt = dbContext.GetService<IDesignTimeModel>().Model; then navigate to the index and call GetVectorIndexType().
- Never read design-time-only annotations (VectorIndexType, configuration sources) from DbContext.Model; treat the runtime model as read-optimized.
- If you must branch on annotation presence at runtime, guard with `index is not RuntimeIndex` before calling.
Example fix
// before (runtime model throws)
var t = context.Model
.FindEntityType(typeof(Item))!.GetIndexes().First().GetVectorIndexType();
// after (design-time model)
var dtModel = context.GetService<IDesignTimeModel>().Model;
var t = dtModel
.FindEntityType(typeof(Item))!.GetIndexes().First().GetVectorIndexType(); Defensive patterns
Strategy: validation
Validate before calling
// Guard before reading a design-time-only annotation.
if (index is RuntimeIndex)
{
var dtIndex = context.GetService<IDesignTimeModel>().Model
.FindEntityType(entityType)!.GetIndexes().ElementAt(i);
return dtIndex.GetVectorIndexType();
}
return index.GetVectorIndexType(); Type guard
static bool IsRuntimeIndex(IReadOnlyIndex index) => index is RuntimeIndex;
Try / catch
try { return index.GetVectorIndexType(); }
catch (InvalidOperationException ex) when (ex.Message.Contains("read-optimized model"))
{ return context.GetService<IDesignTimeModel>().Model /* navigate to index */ .GetVectorIndexType(); } Prevention
- Always read Cosmos index annotations from IDesignTimeModel, not DbContext.Model.
- Treat DbContext.Model as read-optimized for query execution only.
- Guard annotation reads with `index is not RuntimeIndex` when the source is uncertain.
When it happens
Trigger: Calling index.GetVectorIndexType() where the index was obtained by navigating DbContext.Model (the runtime/cached model) — e.g. metadata inspection code, diagnostics, or a compiled-model path that hands back a RuntimeIndex.
Common situations: Building tooling/migrations that read index metadata at runtime; assuming DbContext.Model and the design-time model are equivalent; iterating model.GetEntityTypes().SelectMany(e => e.GetIndexes()) and reading Cosmos annotations.
Related errors
- The value '{value}' provided for argument '{argumentName}' m
- 'Except' cannot be called on the builder returned by 'HasAut
- The type '{clrType}' is being used as a vector, but the vect
- The '{parameter}' value passed to '{methodName}' must be a c
- The 'VectorDistance' function can only be used with a proper
AI-assisted analysis of dotnet/efcore@dbf9771522 (2026-08-06).
Data as JSON: /api/errors/060f88b8772a294a.
Report an issue: GitHub.