dotnet/efcore · error · InvalidOperationException
Invalid token type: ' '.
Error message
Invalid token type: '{tokenType}'. What it means
CosmosJsonNumberProjectionReaderWriter<T>.FromJsonTyped reads a numeric projection from a JSON token. It calls Utf8JsonReader.TryGetDouble; if that returns false the token is not a number (e.g. String, Null, True, PropertyName). EF then throws CoreStrings.JsonReaderInvalidTokenType with the actual token type, because it expected to materialize a numeric value.
Solutions
- Correct the stored JSON so the property is emitted as a JSON number (and not null) for that document.
- Make the property nullable in the model if nulls are legitimately possible, so a different reader/writer handles null.
- Audit documents that violate the schema (e.g. with a Cosmos query for items where IS_NUMBER(prop) = false) and repair them.
Example fix
// before - stored document
{ "score": "42" } // string token, TryGetDouble fails
// after
{ "score": 42 } // numeric token
// or, in the model, allow null:
public int? Score { get; set; } Defensive patterns
Strategy: validation
Validate before calling
// Before reading, verify stored values are numeric for projected properties // (run a one-off Cosmos query) // SELECT c.id FROM c WHERE NOT IS_NUMBER(c.score) // Repair any documents returned before running the EF query.
Type guard
// When materializing from arbitrary JSON, narrow before mapping
static bool IsNumericToken(ref Utf8JsonReader r)
=> r.TokenType == JsonTokenType.Number
|| (r.TokenType == JsonTokenType.String
&& double.TryParse(r.GetString(), out _)); Try / catch
try { return await dbContext.Set<Item>().ToListAsync(ct); }
catch (InvalidOperationException ex) when (ex.Message.Contains("Invalid token type"))
{
// run a Cosmos query to find documents where the numeric prop is not a number,
// repair them, then retry the read.
} Prevention
- Keep numeric properties stored as JSON numbers.
- Make properties nullable if the column can be absent/null.
- Validate data before importing it into Cosmos.
When it happens
Trigger: Reading a Cosmos document where a property mapped as a numeric projection (int/long/float/etc.) contains a non-numeric JSON value. TryGetDouble fails for tokens like Null, String, Boolean, or when the reader is positioned on a PropertyName rather than a value. See CosmosJsonNumberProjectionReaderWriter.cs:35.
Common situations: Storing data outside EF (or with a different model) so that a numeric column ends up as a JSON string or null. Schema drift between model and stored documents. Migrating data where numbers were serialized as strings. A null in a non-nullable numeric field.
Understand the failure class
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- Complex projections in subqueries are currently unsupported.
- The LINQ expression ' ' could not be translated. Either…
- The LINQ expression ' ' could not be translated. Either…
- The query uses 'NoTrackingWithIdentityResolution' and…
- The specified entity type
AI-assisted analysis of dotnet/efcore@3a2006ef56 (2026-08-11).
Data as JSON: /api/errors/1af626c52fa808c9.
Report an issue: GitHub.
Appendix: 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 3a2006ef56)