dotnet/efcore · error · InvalidOperationException
Invalid token type: '{tokenType}'.
Error message
Invalid token type: '{tokenType}'. What it means
CosmosJsonNumberProjectionReaderWriter<T>.FromJsonTyped (CosmosJsonNumberProjectionReaderWriter.cs:32-35) reads a projected numeric column. Cosmos projects all numbers as double-precision floating point, so the reader calls TryGetDouble. If the JSON token is not a number (e.g., String, Null, True, StartObject), TryGetDouble returns false and the code throws indicating the unexpected token type. This is typically a data/schema mismatch where a value that EF expects to be numeric is stored as a different JSON type.
Source
Thrown at src/EFCore.Cosmos/Storage/Internal/CosmosJsonNumberProjectionReaderWriter.cs:35
/// Projections of numbers in cosmos can result in double precision floating point numbers,
/// and thus have to be read as doubles to prevent reader exceptions
/// </remarks>
public sealed class CosmosJsonNumberProjectionReaderWriter<T> : JsonValueReaderWriter<T>
where T : INumber<T>
{
private static readonly PropertyInfo
InstanceProperty = typeof(CosmosJsonNumberProjectionReaderWriter<T>).GetProperty(nameof(Instance))!;
/// <summary>
/// The singleton instance of this stateless reader/writer.
/// </summary>
public static CosmosJsonNumberProjectionReaderWriter<T> Instance { get; } = new();
/// <inheritdoc />
public override T FromJsonTyped(ref Utf8JsonReaderManager manager, object? existingObject = null)
=> manager.CurrentReader.TryGetDouble(out var d)
? T.CreateChecked(d) // #38138
: throw new InvalidOperationException(CoreStrings.JsonReaderInvalidTokenType(manager.CurrentReader.TokenType));
/// <inheritdoc />
public override void ToJsonTyped(Utf8JsonWriter writer, T value)
{
if (typeof(T) == typeof(int)
|| typeof(T) == typeof(short)
|| typeof(T) == typeof(sbyte)
|| typeof(T) == typeof(byte)
|| typeof(T) == typeof(ushort))
{
writer.WriteNumberValue(int.CreateChecked(value));
}
else if (typeof(T) == typeof(uint))
{
writer.WriteNumberValue(uint.CreateChecked(value));
}
else if (typeof(T) == typeof(long))
{View on GitHub (pinned to dbf9771522)
Solutions
- Ensure numeric properties are stored as JSON numbers in the container, not strings or other types. If data was written incorrectly, migrate it to numeric form.
- If you intentionally store numbers as strings, configure an appropriate value converter AND a matching JsonValueReaderWriter so EF reads the correct token type.
- Check for null values in non-nullable numeric columns and either make the property nullable or fix the data.
- Inspect the stored document JSON (e.g., via Cosmos Data Explorer) to identify the token-type mismatch.
Example fix
// before — data stored as "count": "42" (string)
// EF reads int, TryGetDouble fails on string token
// after — fix the stored data to numeric
// "count": 42
// or configure a reader/writer if string storage is intentional:
modelBuilder.Entity<Item>()
.Property(i => i.Count)
.HasConversion(
v => v.ToString(),
v => int.Parse(v));
// and ensure the JsonValueReaderWriter handles string tokens Defensive patterns
Strategy: try-catch
Validate before calling
// Before querying, verify stored data types match the model by sampling a document via the Cosmos SDK.
var container = cosmosClient.GetContainer(db, containerName);
var sample = await container.ReadItemAsync<JObject>(someId, new PartitionKey(pk));
var token = sample.Resource["count"]?.Type;
if (token != JTokenType.Integer && token != JTokenType.Float)
throw new InvalidOperationException($"Stored 'count' is {token}, expected numeric."); Try / catch
// Catch during query and log the property/token for diagnosis.
try { var results = await db.Items.Where(i => i.Count > 0).ToListAsync(); }
catch (InvalidOperationException ex) when (ex.Message.Contains("Invalid token type"))
{ /* inspect stored JSON, fix data or converter, then retry */ } Prevention
- Ensure numeric properties are stored as JSON numbers, not strings.
- If using value converters that change the wire type, configure a matching JsonValueReaderWriter.
- Validate sample documents via Cosmos Data Explorer before relying on EF queries.
- Add data-integration tests that round-trip numeric properties through save and query.
When it happens
Trigger: Querying a property that EF maps as a numeric type (int, long, decimal, etc.) but whose stored JSON value is a string, null, boolean, or object. This happens when data was written outside EF (e.g., via raw SDK or migration tool) with a different type, or when a value converter changes the on-wire representation in a way that conflicts with the projection reader.
Common situations: Storing numbers as JSON strings in the container (e.g., "42" instead of 42) via a different writer. Using a value converter that serializes numbers as strings but EF's projection reader expects a numeric token. Schema drift after changing a property type. Reading data inserted by a legacy app that stringified numbers.
Understand the failure class
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- The type '{givenType}' cannot be mapped as a dictionary beca
- The partition key value supplied for '{propertyType}' proper
- Property '{entityType}.{property}' was configured for full-t
- The value '{value}' provided for argument '{argumentName}' m
- Cosmos-specific methods can only be used when the context is
AI-assisted analysis of dotnet/efcore@dbf9771522 (2026-08-06).
Data as JSON: /api/errors/1af626c52fa808c9.
Report an issue: GitHub.