OpenRA/OpenRA · error · LuaException

Invalid data type for '{initInstance[0]}.{key}' (expected {t

Error message

Invalid data type for '{initInstance[0]}.{key}' (expected {type.Name}, got {kv.Value.WrappedClrType()})

What it means

Raised in the CompositeActorInit path when a field key is valid but the Lua value cannot be coerced to the .NET type that field expects. TryGetClrValue fails and the engine reports both the expected type name and the actual wrapped CLR type of the Lua value.

Source

Thrown at OpenRA.Mods.Common/Scripting/Global/ActorGlobal.cs:61

			if (value is LuaTable tableValue && init is CompositeActorInit compositeInit)
			{
				var args = compositeInit.InitializeArgs();
				var initValues = new Dictionary<string, object>();
				foreach (var kv in tableValue)
				{
					using (kv.Key)
					using (kv.Value)
					{
						var key = kv.Key.ToString();
						if (!args.TryGetValue(key, out var type))
							throw new LuaException($"Unknown initializer type '{initInstance[0]}.{key}'");

						var isActorReference = type == typeof(ActorInitActorReference);
						if (isActorReference)
							type = kv.Value is LuaString ? typeof(string) : typeof(Actor);

						if (!kv.Value.TryGetClrValue(type, out var clrValue))
							throw new LuaException($"Invalid data type for '{initInstance[0]}.{key}' (expected {type.Name}, got {kv.Value.WrappedClrType()})");

						if (isActorReference)
							clrValue = type == typeof(string) ? new ActorInitActorReference((string)clrValue) : new ActorInitActorReference((Actor)clrValue);

						initValues[key] = clrValue;
					}
				}

				compositeInit.Initialize(initValues);
				return init;
			}

			var initializers = initType.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)
				.Where(m => m.Name == "Initialize" && m.GetParameters().Length == 1)
				.ToList();

			foreach (var initializer in initializers)
			{

View on GitHub (pinned to a520984d91)

Solutions

  1. Match the Lua value type to the field's expected .NET type (read the error's 'expected X' and convert: tonumber, tostring, or build the expected object).
  2. Use tonumber()/explicit construction in Lua for numeric fields.
  3. For actor references, pass a string actor id or an Actor object per the ActorInitActorReference handling.

Example fix

-- before
Actor.Create("e1", true, { Owner = player, Facing = { Facing = "north" } })
-- after
Actor.Create("e1", true, { Owner = player, Facing = { Facing = 0 } })
Defensive patterns

Strategy: type-guard

Validate before calling

-- Coerce Lua values to expected types before placing in a composite init table.
local function AsInt(v) return assert(tonumber(v), "expected number") end
initTable.Facing = { Facing = AsInt(rawFacing) }

Type guard

local function IsNumber(v) return type(v) == "number" end

Prevention

When it happens

Trigger: Passing a string to a numeric composite field, a number where an actor reference/table is required, or a LuaValue of the wrong wrapper type. Example: { Facing = { Facing = "north" } } where Facing expects an integer angle.

Common situations: Lua's dynamic typing letting a string slip into a numeric field; passing a Lua table where a scalar is expected; off-by-format errors like giving a WAngle/number mismatch.

Related errors


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