{"record":{"id":"1af626c52fa808c9","repo":"dotnet/efcore","slug":"invalid-token-type-tokentype-1af626","errorCode":null,"errorMessage":"Invalid token type: '{tokenType}'.","messagePattern":"Invalid token type: '(.+?)'\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/EFCore.Cosmos/Storage/Internal/CosmosJsonNumberProjectionReaderWriter.cs","lineNumber":35,"sourceCode":"///     Projections of numbers in cosmos can result in double precision floating point numbers,\n///     and thus have to be read as doubles to prevent reader exceptions\n/// </remarks>\npublic sealed class CosmosJsonNumberProjectionReaderWriter<T> : JsonValueReaderWriter<T>\n    where T : INumber<T>\n{\n    private static readonly PropertyInfo\n        InstanceProperty = typeof(CosmosJsonNumberProjectionReaderWriter<T>).GetProperty(nameof(Instance))!;\n\n    /// <summary>\n    ///     The singleton instance of this stateless reader/writer.\n    /// </summary>\n    public static CosmosJsonNumberProjectionReaderWriter<T> Instance { get; } = new();\n\n    /// <inheritdoc />\n    public override T FromJsonTyped(ref Utf8JsonReaderManager manager, object? existingObject = null)\n        => manager.CurrentReader.TryGetDouble(out var d)\n            ? T.CreateChecked(d) // #38138\n            : throw new InvalidOperationException(CoreStrings.JsonReaderInvalidTokenType(manager.CurrentReader.TokenType));\n\n    /// <inheritdoc />\n    public override void ToJsonTyped(Utf8JsonWriter writer, T value)\n    {\n        if (typeof(T) == typeof(int)\n            || typeof(T) == typeof(short)\n            || typeof(T) == typeof(sbyte)\n            || typeof(T) == typeof(byte)\n            || typeof(T) == typeof(ushort))\n        {\n            writer.WriteNumberValue(int.CreateChecked(value));\n        }\n        else if (typeof(T) == typeof(uint))\n        {\n            writer.WriteNumberValue(uint.CreateChecked(value));\n        }\n        else if (typeof(T) == typeof(long))\n        {","sourceCodeStart":17,"sourceCodeEnd":53,"githubUrl":"https://github.com/dotnet/efcore/blob/3a2006ef569de08368d59db5e1468aa8f407e4f8/src/EFCore.Cosmos/Storage/Internal/CosmosJsonNumberProjectionReaderWriter.cs#L17-L53","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before - stored document\n{ \"score\": \"42\" }   // string token, TryGetDouble fails\n\n// after\n{ \"score\": 42 }    // numeric token\n// or, in the model, allow null:\npublic int? Score { get; set; }","handlingStrategy":"validation","validationCode":"// Before reading, verify stored values are numeric for projected properties\n// (run a one-off Cosmos query)\n// SELECT c.id FROM c WHERE NOT IS_NUMBER(c.score)\n// Repair any documents returned before running the EF query.","typeGuard":"// When materializing from arbitrary JSON, narrow before mapping\nstatic bool IsNumericToken(ref Utf8JsonReader r)\n    => r.TokenType == JsonTokenType.Number\n       || (r.TokenType == JsonTokenType.String\n           && double.TryParse(r.GetString(), out _));","tryCatchPattern":"try { return await dbContext.Set<Item>().ToListAsync(ct); }\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"Invalid token type\"))\n{\n    // run a Cosmos query to find documents where the numeric prop is not a number,\n    // repair them, then retry the read.\n}","preventionTips":["Keep numeric properties stored as JSON numbers.","Make properties nullable if the column can be absent/null.","Validate data before importing it into Cosmos."],"tags":["cosmos","json-serialization","numeric","projection","data-corruption"],"backgroundTag":null,"analyzedSha":"3a2006ef569de08368d59db5e1468aa8f407e4f8","analyzedAt":"2026-08-11T23:42:04.146Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}