{"record":{"id":"9285abbb4c9d2d8b","repo":"OpenRA/OpenRA","slug":"error-parsing-gamespeed-node-key-label-e-mi","errorCode":null,"errorMessage":"Error parsing GameSpeed {node.Key}: {label}: {e.Missing.JoinWith(\", \")}","messagePattern":"Error parsing GameSpeed (.+?): (.+?): (.+?)","errorType":"exception","errorClass":"YamlException","httpStatus":null,"severity":"error","filePath":"OpenRA.Game/GameSpeed.cs","lineNumber":55,"sourceCode":"\t\tpublic readonly Dictionary<string, GameSpeed> Speeds;\n\n\t\tstatic object LoadSpeeds(MiniYaml y)\n\t\t{\n\t\t\tvar ret = new Dictionary<string, GameSpeed>();\n\t\t\tvar speedsNode = y.NodeWithKeyOrDefault(\"Speeds\");\n\t\t\tif (speedsNode == null)\n\t\t\t\tthrow new YamlException(\"Error parsing GameSpeeds: Missing Speeds node!\");\n\n\t\t\tforeach (var node in speedsNode.Value.Nodes)\n\t\t\t{\n\t\t\t\ttry\n\t\t\t\t{\n\t\t\t\t\tret.Add(node.Key, FieldLoader.Load<GameSpeed>(node.Value));\n\t\t\t\t}\n\t\t\t\tcatch (FieldLoader.MissingFieldsException e)\n\t\t\t\t{\n\t\t\t\t\tvar label = e.Missing.Length > 1 ? \"Required properties missing\" : \"Required property missing\";\n\t\t\t\t\tthrow new YamlException($\"Error parsing GameSpeed {node.Key}: {label}: {e.Missing.JoinWith(\", \")}\");\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn ret;\n\t\t}\n\t}\n}\n","sourceCodeStart":37,"sourceCodeEnd":63,"githubUrl":"https://github.com/OpenRA/OpenRA/blob/a520984d91eda9de48a62b1d15c1e3bad0d4fb1a/OpenRA.Game/GameSpeed.cs#L37-L63","documentation":"Thrown by GameSpeed.LoadSpeeds when FieldLoader.Load<GameSpeed> for an individual speed entry raises MissingFieldsException because a [FieldLoader.Require] field (e.g. Timestep) is absent. The message names the speed key and lists the missing required properties.","triggerScenarios":"Loading a Speeds child node whose GameSpeed mapping omits a required field, so FieldLoader.Load throws MissingFieldsException that is re-wrapped with the node key and missing field list.","commonSituations":"A speed entry missing Timestep or another required field after a SDK change added a new mandatory field; incomplete copy of a speed definition; a renamed field whose old key remains.","solutions":["Add the listed missing required field(s) to the named speed entry under Speeds.","Check the GameSpeed class for the exact required field names and types.","After a SDK upgrade, lint mod.yaml to surface newly-required speed fields.","Copy a complete speed entry from a reference mod and adjust values."],"exampleFix":"# mod.yaml - before\nSpeeds:\n    default:\n        DefaultSpeed: default\n# after - add required Timestep\nSpeeds:\n    default:\n        Timestep: 40\n        DefaultSpeed: default","handlingStrategy":"validation","validationCode":"// Validate each speed entry has required GameSpeed fields before loading\nvar required = typeof(GameSpeed).GetFields()\n    .Where(f => f.GetCustomAttribute<FieldLoader.RequireAttribute>() != null)\n    .Select(f => f.Name);\nvar present = node.Value.Nodes.Select(n => n.Key).ToHashSet();\nvar missing = required.Where(r => !present.Contains(r)).ToList();\nif (missing.Count > 0) // report missing fields before FieldLoader.Load","typeGuard":null,"tryCatchPattern":"try { /* load Speeds */ }\ncatch (YamlException ex) when (ex.Message.Contains(\"Error parsing GameSpeed\"))\n{ /* add the listed missing fields to the named speed entry */ }","preventionTips":["Copy complete speed entries from a reference mod.","After SDK upgrades, lint mod.yaml for newly-required speed fields.","Confirm required field names against the GameSpeed class."],"tags":["gamespeed","yaml","fieldloader","mod-config","openra"],"backgroundTag":null,"analyzedSha":"a520984d91eda9de48a62b1d15c1e3bad0d4fb1a","analyzedAt":"2026-08-13T15:30:14.787Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}