{"record":{"id":"6c5408f221114f62","repo":"stride3d/stride","slug":"the-path-tostring-contains-a-null-item-on-a-set","errorCode":null,"errorMessage":"The path [{ToString()}] contains a null item on a set.","messagePattern":"The path \\[(.+?)\\] contains a null item on a set\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"sources/assets/Stride.Core.Assets/Yaml/YamlAssetPath.cs","lineNumber":261,"sourceCode":"                    {\n                        var typeDescriptor = TypeDescriptorFactory.Default.Find(currentObject.GetType());\n                        if (typeDescriptor is ArrayDescriptor arrayDescriptor)\n                        {\n                            if (item.Value is not int)\n                            {\n                                throw new InvalidOperationException($\"The path [{ToString()}] contains non-integer index on an array.\");\n                            }\n                            int value = (int)item.Value;\n                            memberPath.Push(arrayDescriptor, value);\n                            currentObject = arrayDescriptor.GetValue(currentObject, value);\n                        }\n                        else if (typeDescriptor is CollectionDescriptor collectionDescriptor)\n                        {\n                            if (collectionDescriptor is SetDescriptor setDescriptor)\n                            {\n                                if (item.Value is null && !collectionDescriptor.ElementType.IsNullable())\n                                {\n                                    throw new InvalidOperationException($\"The path [{ToString()}] contains a null item on a set.\");\n                                }\n                                if (!setDescriptor.Contains(currentObject, item.Value))\n                                {\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                        }","sourceCodeStart":243,"sourceCodeEnd":279,"githubUrl":"https://github.com/stride3d/stride/blob/96fad776d210c221682aac1ccdf4c79dc046fc38/sources/assets/Stride.Core.Assets/Yaml/YamlAssetPath.cs#L243-L279","documentation":"Thrown by YamlAssetPath.ToMemberPath when a path element references a null item in a set whose element type does not allow nulls. Sets are addressed by the item value itself, so a null (or a null not permitted by the element type) cannot identify any member and the conversion is aborted.","triggerScenarios":"ToMemberPath processes an element whose parent resolves to a SetDescriptor and item.Value is null while collectionDescriptor.ElementType.IsNullable() is false.","commonSituations":"A YAML asset path referencing an empty/null entry of a HashSet-based property; schema changes that made a set's element type non-nullable after the asset was authored; hand-edited YAML inserting a null set key.","solutions":["Remove the null entry from the path in the asset YAML or regenerate the reference to point at an actual set element","If nulls are legitimate, change the set's element type to a nullable one in the asset class","Fix code that builds the YamlAssetPath so it never pushes a null item for a set","Catch InvalidOperationException in ToMemberPath callers and log the path for diagnosis"],"exampleFix":"// before (asset yaml)\nsetItems: [null]\n// after\nsetItems: [myItemId]","handlingStrategy":"validation","validationCode":"if (item.Value is null && !elementType.IsNullable()) throw new ArgumentException(\"Set items cannot be null for non-nullable element types\");","typeGuard":"bool IsValidSetItem(object v) => v != null;","tryCatchPattern":"try { memberPath = yamlPath.ToMemberPath(); } catch (InvalidOperationException ex) { log.Error($\"Invalid set reference in '{yamlPath}': {ex.Message}\"); }","preventionTips":["Never serialize null entries inside set-typed asset properties","Ensure set element types are non-nullable or explicitly nullable as intended","Validate asset YAML paths after schema changes to asset classes","Re-save assets after refactoring collection types"],"tags":["yaml","asset-path","sets","null"],"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"}