{"record":{"id":"7089bc6243988b12","repo":"OpenRA/OpenRA","slug":"attempted-to-call-cvec-subtract-cvec-cvec-with-i","errorCode":null,"errorMessage":"Attempted to call CVec.Subtract(CVec, CVec) with invalid arguments ({left.WrappedClrType().Name}, {right.WrappedClrType().Name})","messagePattern":"Attempted to call CVec\\.Subtract\\(CVec, CVec\\) with invalid arguments \\((.+?), (.+?)\\)","errorType":"exception","errorClass":"LuaException","httpStatus":null,"severity":"error","filePath":"OpenRA.Game/CVec.cs","lineNumber":90,"sourceCode":"\t\t\tnew(1,  0),\n\t\t\tnew(1,  1),\n\t\t];\n\n\t\t#region Scripting interface\n\n\t\tpublic LuaValue Add(LuaRuntime runtime, LuaValue left, LuaValue right)\n\t\t{\n\t\t\tif (!left.TryGetClrValue(out CVec a) || !right.TryGetClrValue(out CVec b))\n\t\t\t\tthrow new LuaException(\"Attempted to call CVec.Add(CVec, CVec) with invalid arguments \" +\n\t\t\t\t\t$\"({left.WrappedClrType().Name}, {right.WrappedClrType().Name})\");\n\n\t\t\treturn new LuaCustomClrObject(a + b);\n\t\t}\n\n\t\tpublic LuaValue Subtract(LuaRuntime runtime, LuaValue left, LuaValue right)\n\t\t{\n\t\t\tif (!left.TryGetClrValue(out CVec a) || !right.TryGetClrValue(out CVec b))\n\t\t\t\tthrow new LuaException(\"Attempted to call CVec.Subtract(CVec, CVec) with invalid arguments \" +\n\t\t\t\t\t$\"({left.WrappedClrType().Name}, {right.WrappedClrType().Name})\");\n\n\t\t\treturn new LuaCustomClrObject(a - b);\n\t\t}\n\n\t\tpublic LuaValue Equals(LuaRuntime runtime, LuaValue left, LuaValue right)\n\t\t{\n\t\t\tif (!left.TryGetClrValue(out CVec a) || !right.TryGetClrValue(out CVec b))\n\t\t\t\treturn false;\n\n\t\t\treturn a == b;\n\t\t}\n\n\t\tpublic LuaValue Minus(LuaRuntime runtime)\n\t\t{\n\t\t\treturn new LuaCustomClrObject(-this);\n\t\t}\n","sourceCodeStart":72,"sourceCodeEnd":108,"githubUrl":"https://github.com/OpenRA/OpenRA/blob/a520984d91eda9de48a62b1d15c1e3bad0d4fb1a/OpenRA.Game/CVec.cs#L72-L108","documentation":"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.","triggerScenarios":"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.","commonSituations":"Operand type confusion between CVec, CPos, and WVec in Lua mission scripts. Attempting to subtract a number from a vector instead of dividing.","solutions":["Ensure both operands are CVec values. If subtracting two CPos values, do it on the CPos (posA - posB yields a CVec).","If scaling a CVec, use multiplication or division by an integer, not subtraction.","Check the type names in the error message to locate the wrong operand."],"exampleFix":"-- before\nlocal diff = myVec - myPos -- invalid: CVec - CPos\n\n-- after\nlocal diff = myPosB - myPosA -- CPos - CPos yields CVec","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"-- Verify both operands are CVec before subtraction\nfunction isCVec(v)\n    local t\n    pcall(function() t = v.WrappedClrType().Name end)\n    return t == \"CVec\"\nend","tryCatchPattern":"local ok, result = pcall(function() return vecA - vecB end)\nif not ok then\n    print(\"CVec.Subtract failed: \" .. tostring(result))\nend","preventionTips":["For CPos - CPos (which yields CVec), call subtraction on the CPos, not on a CVec.","For scaling use multiplication/division, not subtraction.","Double-check operand types when chaining operations in scripts."],"tags":["cvec","lua","scripting","openra","type-mismatch"],"backgroundTag":null,"analyzedSha":"a520984d91eda9de48a62b1d15c1e3bad0d4fb1a","analyzedAt":"2026-08-13T15:30:14.787Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}