{"record":{"id":"d2865e2701fa6372","repo":"OpenRA/OpenRA","slug":"there-is-more-than-one-locomotor-named-locomotor-d2865e","errorCode":null,"errorMessage":"There is more than one locomotor named '{Locomotor}'.","messagePattern":"There is more than one locomotor named '(.+?)'\\.","errorType":"exception","errorClass":"YamlException","httpStatus":null,"severity":"error","filePath":"OpenRA.Mods.Common/Traits/Mobile.cs","lineNumber":113,"sourceCode":"\t\tIEnumerable<ActorInit> IActorPreviewInitInfo.ActorPreviewInits(ActorInfo ai, ActorPreviewType type)\n\t\t{\n\t\t\tyield return new FacingInit(PreviewFacing);\n\t\t}\n\n\t\tpublic Color GetTargetLineColor() { return TargetLineColor; }\n\n\t\tpublic override object Create(ActorInitializer init) { return new Mobile(init, this); }\n\n\t\tpublic LocomotorInfo LocomotorInfo { get; private set; }\n\n\t\tpublic override void RulesetLoaded(Ruleset rules, ActorInfo ai)\n\t\t{\n\t\t\tvar locomotorInfos = rules.Actors[SystemActors.World].TraitInfos<LocomotorInfo>()\n\t\t\t\t.Where(li => li.Name == Locomotor).ToList();\n\t\t\tif (locomotorInfos.Count == 0)\n\t\t\t\tthrow new YamlException($\"A locomotor named '{Locomotor}' doesn't exist.\");\n\t\t\telse if (locomotorInfos.Count > 1)\n\t\t\t\tthrow new YamlException($\"There is more than one locomotor named '{Locomotor}'.\");\n\n\t\t\tLocomotorInfo = locomotorInfos[0];\n\n\t\t\t// We need to reset the reference to the locomotor between each worlds, otherwise we are reference the previous state.\n\t\t\tlocomotor = null;\n\n\t\t\tbase.RulesetLoaded(rules, ai);\n\t\t}\n\n\t\tpublic WAngle GetInitialFacing() { return InitialFacing; }\n\n\t\t// initialized and used by CanEnterCell\n\t\tLocomotor locomotor;\n\n\t\t/// <summary>\n\t\t/// Note: If the target <paramref name=\"cell\"/> has any free subcell, the value of <paramref name=\"subCell\"/> is ignored.\n\t\t/// </summary>\n\t\tpublic bool CanEnterCell(World world, Actor self, CPos cell,","sourceCodeStart":95,"sourceCodeEnd":131,"githubUrl":"https://github.com/OpenRA/OpenRA/blob/a520984d91eda9de48a62b1d15c1e3bad0d4fb1a/OpenRA.Mods.Common/Traits/Mobile.cs#L95-L131","documentation":"Same lookup as error 414, but this fires when more than one world-level Locomotor trait shares the same Name. Mobile can only resolve to a single locomotor, so an ambiguous name is rejected. The first one found is not silently chosen.","triggerScenarios":"Two or more Locomotor traits on the world actor with identical Name fields, while a Mobile references that name. Often happens when copy-pasting a locomotor definition without changing its Name.","commonSituations":"Adding a second locomotor variant and forgetting to give it a unique Name, or merging rules files that each define a 'default' locomotor.","solutions":["Give each Locomotor trait a unique Name.","Update the relevant Mobile.Locomotor references to the intended unique name.","Remove the duplicate Locomotor trait."],"exampleFix":"# before\n^Locomotor@land:\n  Name: land\n^Locomotor@land2:\n  Name: land\n# after\n^Locomotor@land:\n  Name: land\n^Locomotor@land2:\n  Name: land2","handlingStrategy":"validation","validationCode":"var names = rules.Actors[SystemActors.World].TraitInfos<LocomotorInfo>()\n    .Select(li => li.Name).ToList();\nvar dups = names.GroupBy(n => n).Where(g => g.Count() > 1).Select(g => g.Key);\nif (dups.Any())\n    report($\"Duplicate Locomotor names: {string.Join(',', dups)}\");","typeGuard":"static bool LocomotorNamesUnique(Ruleset rules)\n    => !rules.Actors[SystemActors.World].TraitInfos<LocomotorInfo>()\n           .GroupBy(li => li.Name).Any(g => g.Count() > 1);","tryCatchPattern":null,"preventionTips":["Give every Locomotor a unique Name even if its Type differs.","Lint world rules for duplicate Locomotor.Name values."],"tags":["openra","movement","locomotor","ruleset-validation","yaml"],"backgroundTag":null,"analyzedSha":"a520984d91eda9de48a62b1d15c1e3bad0d4fb1a","analyzedAt":"2026-08-13T15:30:14.787Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}