{"record":{"id":"02dd3d957ed7e345","repo":"JosefNemec/Playnite","slug":"can-t-assign-object-to-uknown-dat-property","errorCode":null,"errorMessage":"Can't assign object to uknown dat property.","messagePattern":"Can't assign object to uknown dat property\\.","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"source/Tools/Playnite.Utilities/DatParser.cs","lineNumber":94,"sourceCode":"            foreach (var prop in datObj.Properties)\r\n            {\r\n                var romAdded = false;\r\n                if (prop.Name == \"rom\" && !romAdded)\r\n                {\r\n                    romAdded = true;\r\n                    foreach (var romDatProp in (prop.Value as DatObject).Properties)\r\n                    {\r\n                        if (datGameProperties.TryGetValue(\"rom.\" + romDatProp.Name, out var romPropInfo))\r\n                        {\r\n                            SetParsedProperty(romPropInfo, datGame, (string)romDatProp.Value);\r\n                        }\r\n                    }\r\n                }\r\n                else if (datGameProperties.TryGetValue(prop.Name, out var propInfo))\r\n                {\r\n                    if (prop.Value is DatObject)\r\n                    {\r\n                        throw new Exception(\"Can't assign object to uknown dat property.\");\r\n                    }\r\n\r\n                    SetParsedProperty(propInfo, datGame, (string)prop.Value);\r\n                }\r\n            }\r\n\r\n            datGame.FixData();\r\n            return datGame;\r\n        }\r\n\r\n        private void SetParsedProperty(PropertyInfo prop, object datGame, string propValue)\r\n        {\r\n            if (prop.PropertyType == typeof(uint))\r\n            {\r\n                prop.SetValue(datGame, uint.Parse(propValue));\r\n            }\r\n            else if (prop.PropertyType == typeof(int))\r\n            {\r","sourceCodeStart":76,"sourceCodeEnd":112,"githubUrl":"https://github.com/JosefNemec/Playnite/blob/5911f4e964e628aa7a69c2030ab35101afa63067/source/Tools/Playnite.Utilities/DatParser.cs#L76-L112","documentation":"Thrown by DatParser when a top-level DAT property name matches a known datGameProperties key, but its value is a nested DatObject rather than a scalar string. Only a few keys (like 'rom') are handled as nested objects; any other key whose value is an object has no target mapping and the parser refuses to guess, raising a generic Exception. Note the misspelling 'uknown' is intentional/consistent with the codebase.","triggerScenarios":"Parsing a .dat file whose structure nests an object under a property name that is recognized but not the 'rom' container — i.e. a DAT object whose Name collides with a flat datGame property but whose Value is itself a DatObject.","commonSituations":"Custom or non-standard DAT exports that nest data unexpectedly; a DAT from a different emulator/curation tool using object values for fields Playnite expects as scalars; schema drift in an upstream DAT generator.","solutions":["Inspect the offending DAT entry to find which property name carries an object value instead of a string.","If the nested object is legitimate, add an explicit branch in the parser (mirroring the 'rom' handling) to map its sub-properties before this else-if falls through.","Pre-process/sanitize the DAT so recognized keys carry scalar values.","Report the property name upstream so the DAT schema can be corrected."],"exampleFix":"// before\nelse if (datGameProperties.TryGetValue(prop.Name, out var propInfo))\n{\n    if (prop.Value is DatObject)\n        throw new Exception(\"Can't assign object to uknown dat property.\");\n    SetParsedProperty(propInfo, datGame, (string)prop.Value);\n}\n\n// after (handle a legitimate nested container explicitly)\nelse if (prop.Name == \"custom\" && prop.Value is DatObject custom)\n{\n    foreach (var sub in custom.Properties)\n        if (datGameProperties.TryGetValue(\"custom.\" + sub.Name, out var sp))\n            SetParsedProperty(sp, datGame, (string)sub.Value);\n}\nelse if (datGameProperties.TryGetValue(prop.Name, out var propInfo))\n{\n    SetParsedProperty(propInfo, datGame, (string)prop.Value);\n}","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"static bool IsKnownScalarProperty(string name, object value) =>\n    datGameProperties.ContainsKey(name) && !(value is DatObject);\n\n// guard before assignment:\nif (prop.Value is DatObject obj)\n    logger.Warn($\"Skipping nested object on known property '{prop.Name}' — no mapping.\");\nelse\n    SetParsedProperty(propInfo, datGame, (string)prop.Value);","tryCatchPattern":null,"preventionTips":["Validate DAT structure against the expected schema before parsing; flag object values on scalar keys.","Add explicit nested-property branches (like 'rom') for any legitimate container instead of relying on the fallthrough.","Log the offending property name and parent entry when the shape is unexpected to speed diagnosis."],"tags":["dat","parsing","import","type-mismatch"],"backgroundTag":null,"analyzedSha":"5911f4e964e628aa7a69c2030ab35101afa63067","analyzedAt":"2026-08-13T17:38:25.713Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}