{"record":{"id":"b50bbb0573de3922","repo":"dotnet/efcore","slug":"the-type-giventype-cannot-be-mapped-as-a-dicti","errorCode":null,"errorMessage":"The type '{givenType}' cannot be mapped as a dictionary because it does not implement '{dictionaryType}'.","messagePattern":"The type '(.+?)' cannot be mapped as a dictionary because it does not implement '(.+?)'\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/EFCore.Cosmos/ChangeTracking/Internal/StringDictionaryComparer.cs","lineNumber":128,"sourceCode":"        {\n            if (aDictionary.Count != bDictionary.Count)\n            {\n                return false;\n            }\n\n            foreach (var pair in aDictionary)\n            {\n                if (!bDictionary.TryGetValue(pair.Key, out var bValue)\n                    || !elementCompare(pair.Value, bValue))\n                {\n                    return false;\n                }\n            }\n\n            return true;\n        }\n\n        throw new InvalidOperationException(\n            CosmosStrings.BadDictionaryType(\n                (a is IDictionary<string, TElement?> ? b : a).GetType().ShortDisplayName(),\n                typeof(IDictionary<,>).MakeGenericType(typeof(string), typeof(TElement)).ShortDisplayName()));\n    }\n\n    private static int GetHashCode(IEnumerable source, Func<TElement?, int> elementGetHashCode)\n    {\n        if (source is not IReadOnlyDictionary<string, TElement?> sourceDictionary)\n        {\n            throw new InvalidOperationException(\n                CosmosStrings.BadDictionaryType(\n                    source.GetType().ShortDisplayName(),\n                    typeof(IList<>).MakeGenericType(typeof(TElement)).ShortDisplayName()));\n        }\n\n        var hash = new HashCode();\n\n        foreach (var pair in sourceDictionary)","sourceCodeStart":110,"sourceCodeEnd":146,"githubUrl":"https://github.com/dotnet/efcore/blob/dbf9771522148d61a2467854921bd5dc6f6e6916/src/EFCore.Cosmos/ChangeTracking/Internal/StringDictionaryComparer.cs#L110-L146","documentation":"Thrown by StringDictionaryComparer.Compare when the compared object is not an IReadOnlyDictionary<string, TElement>. The Cosmos provider maps dictionary properties via this comparer and expects the runtime type to implement the read-only dictionary interface; anything else is a model/type mismatch. This is an internal EF Core API, so the error usually indicates the property's CLR type is not what the model declared.","triggerScenarios":"A Cosmos-mapped property configured as a string-keyed dictionary whose runtime instance is a non-dictionary collection (e.g., a List<T>, array, or a custom type that does not implement IReadOnlyDictionary<string, T>). Also when TElement mismatches the comparer's generic argument after a model change.","commonSituations":"Changing a property from Dictionary<string,T> to List<T> (or vice versa) without updating the model configuration. Deserializing JSON into a POCO that does not implement the dictionary interface but is mapped as one. Version upgrades where the comparer's required interface changed.","solutions":["Ensure the property's CLR type implements IReadOnlyDictionary<string, TElement> (e.g., use Dictionary<string, T> which implements it).","Align the element type T used in the model with the comparer's TElement.","If the property should be a list/array, reconfigure it as a complex collection rather than a dictionary mapping."],"exampleFix":"// before\npublic List<KeyValuePair<string, int>> Tags { get; set; } // mapped as dictionary\n\n// after\npublic Dictionary<string, int> Tags { get; set; } // implements IReadOnlyDictionary<string,int>","handlingStrategy":"type-guard","validationCode":"if (value is not IReadOnlyDictionary<string, TElement>)\n{\n    throw new InvalidOperationException($\"{value?.GetType()} is not a string-keyed dictionary.\");\n}","typeGuard":"static bool IsStringDictionary<TElement>(object? value)\n    => value is IReadOnlyDictionary<string, TElement>;","tryCatchPattern":null,"preventionTips":["Use Dictionary<string, T> (or another IReadOnlyDictionary<string,T> implementer) for Cosmos dictionary properties.","Keep the property's CLR type aligned with the model mapping after refactors.","Add a model snapshot test that asserts dictionary properties map to the expected comparer."],"tags":["ef-core","cosmos","change-tracking","dictionary","type-mismatch"],"analyzedSha":"dbf9771522148d61a2467854921bd5dc6f6e6916","analyzedAt":"2026-08-06T20:46:03.226Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}