OpenRA/OpenRA · error · YamlException

There is more than one locomotor named '{Locomotor}'.

Error message

There is more than one locomotor named '{Locomotor}'.

What it means

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.

Source

Thrown at OpenRA.Mods.Common/Traits/Mobile.cs:113

		IEnumerable<ActorInit> IActorPreviewInitInfo.ActorPreviewInits(ActorInfo ai, ActorPreviewType type)
		{
			yield return new FacingInit(PreviewFacing);
		}

		public Color GetTargetLineColor() { return TargetLineColor; }

		public override object Create(ActorInitializer init) { return new Mobile(init, this); }

		public LocomotorInfo LocomotorInfo { get; private set; }

		public override void RulesetLoaded(Ruleset rules, ActorInfo ai)
		{
			var locomotorInfos = rules.Actors[SystemActors.World].TraitInfos<LocomotorInfo>()
				.Where(li => li.Name == Locomotor).ToList();
			if (locomotorInfos.Count == 0)
				throw new YamlException($"A locomotor named '{Locomotor}' doesn't exist.");
			else if (locomotorInfos.Count > 1)
				throw new YamlException($"There is more than one locomotor named '{Locomotor}'.");

			LocomotorInfo = locomotorInfos[0];

			// We need to reset the reference to the locomotor between each worlds, otherwise we are reference the previous state.
			locomotor = null;

			base.RulesetLoaded(rules, ai);
		}

		public WAngle GetInitialFacing() { return InitialFacing; }

		// initialized and used by CanEnterCell
		Locomotor locomotor;

		/// <summary>
		/// Note: If the target <paramref name="cell"/> has any free subcell, the value of <paramref name="subCell"/> is ignored.
		/// </summary>
		public bool CanEnterCell(World world, Actor self, CPos cell,

View on GitHub (pinned to a520984d91)

Solutions

  1. Give each Locomotor trait a unique Name.
  2. Update the relevant Mobile.Locomotor references to the intended unique name.
  3. Remove the duplicate Locomotor trait.

Example fix

# before
^Locomotor@land:
  Name: land
^Locomotor@land2:
  Name: land
# after
^Locomotor@land:
  Name: land
^Locomotor@land2:
  Name: land2
Defensive patterns

Strategy: validation

Validate before calling

var names = rules.Actors[SystemActors.World].TraitInfos<LocomotorInfo>()
    .Select(li => li.Name).ToList();
var dups = names.GroupBy(n => n).Where(g => g.Count() > 1).Select(g => g.Key);
if (dups.Any())
    report($"Duplicate Locomotor names: {string.Join(',', dups)}");

Type guard

static bool LocomotorNamesUnique(Ruleset rules)
    => !rules.Actors[SystemActors.World].TraitInfos<LocomotorInfo>()
           .GroupBy(li => li.Name).Any(g => g.Count() > 1);

Prevention

When it happens

Trigger: 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.

Common situations: Adding a second locomotor variant and forgetting to give it a unique Name, or merging rules files that each define a 'default' locomotor.

Related errors


AI-assisted analysis of OpenRA/OpenRA@a520984d91 (2026-08-13). Data as JSON: /api/errors/d2865e2701fa6372. Report an issue: GitHub.