{"record":{"id":"6c058d2a99c64187","repo":"OpenRA/OpenRA","slug":"layer-layer-does-not-exist-on-this-map-valid-la","errorCode":null,"errorMessage":"Layer {layer} does not exist on this map. Valid layers on this map are: {string.Join(\", \", validLayers.Select(x => $\"{x.Index} ({x.Name})\"))}","messagePattern":"Layer (.+?) does not exist on this map\\. Valid layers on this map are: (.+?) \\((.+?)\\)\"\\)\\)\\}","errorType":"exception","errorClass":"LuaException","httpStatus":null,"severity":"error","filePath":"OpenRA.Mods.Common/Scripting/Global/CoordinateGlobals.cs","lineNumber":44,"sourceCode":"\n\t\t[Desc(\"Create a new CPos with the specified coordinates on the specified layer. \" +\n\t\t\t\"The ground is layer 0, other layers have a unique ID. Examples include tunnels, underground, and elevated bridges.\")]\n\t\tpublic CPos NewWithLayer(int x, int y, byte layer)\n\t\t{\n\t\t\tif (layer != 0)\n\t\t\t{\n\t\t\t\tvar worldCmls = Context.World.GetCustomMovementLayers();\n\t\t\t\tif (layer >= worldCmls.Length || worldCmls[layer] == null)\n\t\t\t\t{\n\t\t\t\t\tvar layerNames = typeof(CustomMovementLayerType)\n\t\t\t\t\t\t.GetFields()\n\t\t\t\t\t\t.Select(f => (Index: (byte)f.GetRawConstantValue(), f.Name))\n\t\t\t\t\t\t.ToArray();\n\t\t\t\t\tvar validLayers = new[] { (Index: (byte)0, Name: \"Ground\") }\n\t\t\t\t\t\t.Concat(worldCmls\n\t\t\t\t\t\t\t.Where(cml => cml != null)\n\t\t\t\t\t\t\t.Select(cml => layerNames.Single(ln => ln.Index == cml.Index)));\n\t\t\t\t\tthrow new LuaException($\"Layer {layer} does not exist on this map. \" +\n\t\t\t\t\t\t$\"Valid layers on this map are: {string.Join(\", \", validLayers.Select(x => $\"{x.Index} ({x.Name})\"))}\");\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn new CPos(x, y, layer);\n\t\t}\n\n\t\t[Desc(\"The cell coordinate origin.\")]\n\t\tpublic CPos Zero => CPos.Zero;\n\t}\n\n\t[ScriptGlobal(\"CVec\")]\n\tpublic class CVecGlobal : ScriptGlobal\n\t{\n\t\tpublic CVecGlobal(ScriptContext context)\n\t\t\t: base(context) { }\n\n\t\t[Desc(\"Create a new CVec with the specified coordinates.\")]","sourceCodeStart":26,"sourceCodeEnd":62,"githubUrl":"https://github.com/OpenRA/OpenRA/blob/a520984d91eda9de48a62b1d15c1e3bad0d4fb1a/OpenRA.Mods.Common/Scripting/Global/CoordinateGlobals.cs#L26-L62","documentation":"When constructing a CPos with a non-zero layer, the engine checks the world's custom movement layers array; if the index is out of range or that slot is null (no layer registered at that index) it lists the valid layers by index and name and aborts.","triggerScenarios":"Calling CPos.New(x, y, layer) with a layer index for a custom movement layer (e.g. tunnels, bridges) that the map does not provide; passing an index beyond the registered layers.","commonSituations":"Map without the required custom-layer traits; using a layer index valid in one map but not another; stale index after the map's layers changed.","solutions":["Read the valid layers from the error message and use one of those indices.","Use layer 0 (Ground) when no custom layer is needed.","Ensure the map includes the movement-layer trait (e.g. TunnelLayer, BridgeLayer) if a custom layer is required."],"exampleFix":"-- before\nlocal p = CPos.New(5, 5, 2)  -- layer 2 not on this map\n-- after\nlocal p = CPos.New(5, 5, 0)  -- Ground layer\n-- or use a valid layer index from the error's list","handlingStrategy":"validation","validationCode":"-- Use layer 0 (Ground) unless a known custom layer index is required.\nlocal function SafeCPos(x, y, layer)\n  layer = layer or 0\n  if layer ~= 0 and not ValidLayers[layer] then\n    layer = 0\n  end\n  return CPos.New(x, y, layer)\nend","typeGuard":"local function IsValidLayer(idx)\n  return type(idx) == \"number\" and (idx == 0 or ValidLayers[idx] == true)\nend","tryCatchPattern":"local ok, p = pcall(CPos.New, x, y, layer)\nif not ok then return CPos.New(x, y, 0) end","preventionTips":["Default to ground layer (0).","Cache the map's valid layer indices at script init.","Avoid hardcoding custom layer indices across maps."],"tags":["openra","lua-scripting","coordinates","movement-layer"],"backgroundTag":null,"analyzedSha":"a520984d91eda9de48a62b1d15c1e3bad0d4fb1a","analyzedAt":"2026-08-13T15:30:14.787Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}