OpenRA/OpenRA · error · LuaException
Chronoshift requires a table of actor,cpos pairs. Received {
Error message
Chronoshift requires a table of actor,cpos pairs. Received {kv.Key.WrappedClrType().Name},{kv.Value.WrappedClrType().Name} What it means
Thrown by the Chronoshift Lua scripting property when iterating over a LuaTable of actor→cell-position pairs and a key or value cannot be converted to an Actor or CPos respectively. The method expects a table mapping Actor objects to CPos (cell position) values; receiving any other types causes this error.
Source
Thrown at OpenRA.Mods.Cnc/Scripting/Properties/ChronosphereProperties.cs:38
[ScriptPropertyGroup("Support Powers")]
public class ChronosphereProperties : ScriptActorProperties, Requires<ChronoshiftPowerInfo>
{
public ChronosphereProperties(ScriptContext context, Actor self)
: base(context, self) { }
[Desc("Chronoshift a group of actors. A duration of 0 will teleport the actors permanently. " +
"If a given cell is unexplored for this power's owner, the closest valid cell will be used instead.")]
public void Chronoshift([ScriptEmmyTypeOverride("{ [actor]: cpos }")] LuaTable unitLocationPairs, int duration = 0, bool killCargo = false)
{
foreach (var kv in unitLocationPairs)
{
Actor actor;
CPos cell;
using (kv.Key)
using (kv.Value)
{
if (!kv.Key.TryGetClrValue(out actor) || !kv.Value.TryGetClrValue(out cell))
throw new LuaException($"Chronoshift requires a table of actor,cpos pairs. Received {kv.Key.WrappedClrType().Name},{kv.Value.WrappedClrType().Name}");
}
var cs = actor.TraitsImplementing<Chronoshiftable>()
.FirstEnabledConditionalTraitOrDefault();
if (cs != null && cs.CanChronoshiftTo(actor, cell))
cs.Teleport(actor, cell, duration, killCargo, Self);
}
}
}
}
View on GitHub (pinned to a520984d91)
Solutions
- Ensure the table keys are Actor objects obtained from the scripting API (e.g. Actor.Create or map-defined actors).
- Ensure the table values are CPos values obtained from the map (e.g. Map.CellFromPosition or CPos.New).
- Inspect the error message's type names to identify which key/value has the wrong type.
- Validate the table contents in the script before calling Chronoshift.
Example fix
-- before (Lua):
Chronosphere.Chronoshift({ ["unit1"] = "5,5" })
-- after:
local actor = Map.NamedActors["unit1"]
Chronosphere.Chronoshift({ [actor] = CPos.New(5, 5) }) Defensive patterns
Strategy: validation
Validate before calling
-- In Lua, validate table before calling:
for k, v in pairs(unitLocationPairs) do
if type(k) ~= "table" or k.WrappedClrType == nil then
error("Key must be an Actor")
end
end Type guard
-- Lua guard:
local function isValidChronoshiftTable(t)
for k, v in pairs(t) do
if not k.TryGetClrValue then return false end
end
return true
end Try / catch
local ok, err = pcall(function() Chronosphere.Chronoshift(pairs) end)
if not ok then print("Chronoshift failed: " .. tostring(err)) end Prevention
- Use Actor objects (not strings or IDs) as table keys.
- Use CPos values (not raw numbers) as table values.
- Validate table contents in a pcall to avoid crashing the script.
When it happens
Trigger: Calling the Chronoshift Lua method with a table whose keys are not Actor objects or whose values are not CPos values. TryGetClrValue<Actor> or TryGetClrValue<CPos> returns false, and the error reports the actual wrapped types.
Common situations: A map script passes string IDs instead of Actor objects; cell positions are passed as tables or numbers instead of CPos; the table is nested incorrectly; a script uses positional arguments instead of key-value pairs.
Related errors
- Attempted to call CPos.Add(CPos, CVec) with invalid argument
- Attempted to call CPos.Subtract(CPos, (CPos|CVec)) with inva
- Attempted to call CVec.Add(CVec, CVec) with invalid argument
- Attempted to call CVec.Subtract(CVec, CVec) with invalid arg
- Attempted to call CVec.Multiply(CVec, integer) with invalid
AI-assisted analysis of OpenRA/OpenRA@a520984d91 (2026-08-13).
Data as JSON: /api/errors/139acda22173ff95.
Report an issue: GitHub.