{"record":{"id":"8e95ae9efef48619","repo":"stride3d/stride","slug":"the-path-tostring-contains-a-null-key-on-an-dictionary","errorCode":null,"errorMessage":"The path [{ToString()}] contains a null key on an dictionary.","messagePattern":"The path \\[(.+?)\\] contains a null key on an dictionary\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"sources/assets/Stride.Core.Assets/Yaml/YamlAssetPath.cs","lineNumber":282,"sourceCode":"                                {\n                                    throw new InvalidOperationException($\"The path [{ToString()}] item doesn't exsit on a set.\");\n                                }\n                                memberPath.Push(setDescriptor, item.Value);\n                                currentObject = item.Value;\n                            }\n                            else\n                            {\n                                if (item.Value is not int)\n                                {\n                                    throw new InvalidOperationException($\"The path [{ToString()}] contains non-integer index on a collection.\");\n                                }\n                                memberPath.Push(collectionDescriptor, item.Value);\n                                currentObject = collectionDescriptor.GetValue(currentObject, item.Value);\n                            }\n                        }\n                        else if (typeDescriptor is DictionaryDescriptor dictionaryDescriptor)\n                        {\n                            if (item.Value is null) throw new InvalidOperationException($\"The path [{ToString()}] contains a null key on an dictionary.\");\n                            memberPath.Push(dictionaryDescriptor, item.Value);\n                            currentObject = dictionaryDescriptor.GetValue(currentObject, item.Value);\n                        }\n                        break;\n                    }\n                case ElementType.ItemId:\n                    {\n                        var ids = CollectionItemIdHelper.GetCollectionItemIds(currentObject);\n                        var key = ids.GetKey(item.AsItemId());\n                        var typeDescriptor = TypeDescriptorFactory.Default.Find(currentObject.GetType());\n                        if (typeDescriptor is ArrayDescriptor arrayDescriptor)\n                        {\n                            if (key is not int) throw new InvalidOperationException($\"The path [{ToString()}] contains a non-valid item id on an array.\");\n                            int keyInt = (int)key;\n                            memberPath.Push(arrayDescriptor, keyInt);\n                            currentObject = arrayDescriptor.GetValue(currentObject, keyInt);\n                        }\n                        else if (typeDescriptor is CollectionDescriptor collectionDescriptor)","sourceCodeStart":264,"sourceCodeEnd":300,"githubUrl":"https://github.com/stride3d/stride/blob/96fad776d210c221682aac1ccdf4c79dc046fc38/sources/assets/Stride.Core.Assets/Yaml/YamlAssetPath.cs#L264-L300","documentation":"Thrown by YamlAssetPath.ToMemberPath when a path element targeting a dictionary has a null key. Dictionary entries are addressed by their key, and a null key cannot select any entry, so the library fails fast instead of pushing an invalid MemberPath node.","triggerScenarios":"ToMemberPath resolves the current object to a DictionaryDescriptor and the next path element's Value is null.","commonSituations":"Hand-edited YAML leaving an empty dictionary key; a serializer writing null for a key of a type that permits nulls; programmatic path construction passing null for an unassigned key variable.","solutions":["Fix the dictionary key in the asset YAML to the actual non-null key value","Correct the code building the YamlAssetPath to reject/skip null keys before pushing them","Change dictionary key types so nulls cannot occur (value-type keys)","Guard callers of ToMemberPath with a try/catch on InvalidOperationException and log the full path"],"exampleFix":"// before\npath.Push(dictDescriptor, someKey); // someKey == null\n// after\nif (someKey != null) path.Push(dictDescriptor, someKey);","handlingStrategy":"validation","validationCode":"if (pathItem.Value is null) throw new ArgumentException(\"Dictionary keys cannot be null in asset paths\");","typeGuard":"bool IsValidDictKey(object v) => v != null;","tryCatchPattern":"try { memberPath = yamlPath.ToMemberPath(); } catch (InvalidOperationException ex) { log.Error($\"Null dict key in '{yamlPath}': {ex.Message}\"); }","preventionTips":["Never emit null keys when serializing dictionaries in assets","Prefer value-type (non-nullable) dictionary keys in asset classes","Check hand-edited YAML for empty key entries","Guard path-building code with a null check before pushing keys"],"tags":["yaml","asset-path","dictionary","null-key"],"backgroundTag":"null-argument","analyzedSha":"96fad776d210c221682aac1ccdf4c79dc046fc38","analyzedAt":"2026-09-14T02:59:31.279Z","contentChangedAt":"2026-09-14T02:59:31.279Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}