OpenRA/OpenRA · error · LuaException

Attempted to call CVec.Subtract(CVec, CVec) with invalid arg

Error message

Attempted to call CVec.Subtract(CVec, CVec) with invalid arguments ({left.WrappedClrType().Name}, {right.WrappedClrType().Name})

What it means

Thrown from CVec's Lua subtraction interface when either operand cannot be coerced to a CVec. CVec.Subtract expects two CVec values and returns a CVec. If TryGetClrValue fails on either argument, LuaException is thrown with the actual types.

Source

Thrown at OpenRA.Game/CVec.cs:90

			new(1,  0),
			new(1,  1),
		];

		#region Scripting interface

		public LuaValue Add(LuaRuntime runtime, LuaValue left, LuaValue right)
		{
			if (!left.TryGetClrValue(out CVec a) || !right.TryGetClrValue(out CVec b))
				throw new LuaException("Attempted to call CVec.Add(CVec, CVec) with invalid arguments " +
					$"({left.WrappedClrType().Name}, {right.WrappedClrType().Name})");

			return new LuaCustomClrObject(a + b);
		}

		public LuaValue Subtract(LuaRuntime runtime, LuaValue left, LuaValue right)
		{
			if (!left.TryGetClrValue(out CVec a) || !right.TryGetClrValue(out CVec b))
				throw new LuaException("Attempted to call CVec.Subtract(CVec, CVec) with invalid arguments " +
					$"({left.WrappedClrType().Name}, {right.WrappedClrType().Name})");

			return new LuaCustomClrObject(a - b);
		}

		public LuaValue Equals(LuaRuntime runtime, LuaValue left, LuaValue right)
		{
			if (!left.TryGetClrValue(out CVec a) || !right.TryGetClrValue(out CVec b))
				return false;

			return a == b;
		}

		public LuaValue Minus(LuaRuntime runtime)
		{
			return new LuaCustomClrObject(-this);
		}

View on GitHub (pinned to a520984d91)

Solutions

  1. Ensure both operands are CVec values. If subtracting two CPos values, do it on the CPos (posA - posB yields a CVec).
  2. If scaling a CVec, use multiplication or division by an integer, not subtraction.
  3. Check the type names in the error message to locate the wrong operand.

Example fix

-- before
local diff = myVec - myPos -- invalid: CVec - CPos

-- after
local diff = myPosB - myPosA -- CPos - CPos yields CVec
Defensive patterns

Strategy: type-guard

Type guard

-- Verify both operands are CVec before subtraction
function isCVec(v)
    local t
    pcall(function() t = v.WrappedClrType().Name end)
    return t == "CVec"
end

Try / catch

local ok, result = pcall(function() return vecA - vecB end)
if not ok then
    print("CVec.Subtract failed: " .. tostring(result))
end

Prevention

When it happens

Trigger: In a Lua script, calling vec - value where one or both operands are not CVec. For example, subtracting a CPos from a CVec, or subtracting an integer from a CVec.

Common situations: Operand type confusion between CVec, CPos, and WVec in Lua mission scripts. Attempting to subtract a number from a vector instead of dividing.

Related errors


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