Fix "AddUI: Unknown Parent" for a CUI element in an Oxide plugin
The client console message AddUI: Unknown Parent for "ShopUI.Items": ShopUI.Main means your CuiElementContainer adds a child element whose parent name was never sent to that client (or was destroyed earlier). Create and send the parent panel first, or attach the child directly to the "Overlay" layer.
AddUI: Unknown Parent for "ShopUI.Items": ShopUI.Main
Why it happens
CUI is rendered client-side. Every element in a CuiElementContainer has a parent name string, and the client can only place an element if the parent already exists in its UI tree. The message is printed by the client when it receives an AddUI payload whose parent name is not present. Common triggers in Oxide plugins: calling CuiHelper.AddUi with a container that only holds the child elements, because the parent panel was sent in a separate container that was never added for this player; ordering the parent after the child in the same container; sending only the dynamic part of a UI to a player who relogged, died, or whose UI was wiped by DestroyUi or a respawn; and building a new CuiElementContainer per update while forgetting to re-add the root panel. Names are also case-sensitive and must match the exact string used as the parent of the child.
How to fix it
- Decide the root layer: attach your top panel to "Overlay" (cursor-enabled menus) or "Hud" (passive info) and give it a unique constant name such as
"ShopUI.Main". - Make sure your container adds the root panel before any child element, and that the child's parent string is exactly that name.
- Never send a container that only contains children. Either add everything in one container or resend the parent each time before the children.
- On reload, unload and death, destroy the UI for the player and rebuild from the root so stale state cannot leave orphans.
- Confirm:
oxide.reload ShopUI, open the shop, and check the client F1 console — no AddUI lines should appear while panels open, close, and reopen.
Before and after
using Oxide.Core;
using Oxide.Game.Rust.Cui;
using UnityEngine;
namespace Oxide.Plugins
{
[Info("ShopUI", "RustPluginGenerator", "1.0.0")]
[Description("Opens a small shop panel when a player types /shop.")]
public class ShopUI : RustPlugin
{
private const string MainPanel = "ShopUI.Main";
private const string ItemsPanel = "ShopUI.Items";
[ChatCommand("shop")]
private void CmdShop(BasePlayer player, string command, string[] args)
{
if (player == null) return;
var c = new CuiElementContainer();
// Child references MainPanel, but MainPanel is added later (or never).
c.Add(new CuiPanel
{
Image = { Color = "0.2 0.2 0.2 0.9" },
RectTransform = { AnchorMin = "0.1 0.1", AnchorMax = "0.4 0.4" }
}, MainPanel, ItemsPanel);
c.Add(new CuiLabel
{
Text = { Text = "Items", FontSize = 14, Align = TextAnchor.MiddleCenter },
RectTransform = { AnchorMin = "0 0.8", AnchorMax = "1 1" }
}, ItemsPanel);
c.Add(new CuiPanel
{
Image = { Color = "0.1 0.1 0.1 0.95" },
RectTransform = { AnchorMin = "0.1 0.1", AnchorMax = "0.6 0.6" },
CursorEnabled = true
}, "Overlay", MainPanel);
CuiHelper.DestroyUi(player, MainPanel);
CuiHelper.AddUi(player, c);
}
}
}using Oxide.Core;
using Oxide.Game.Rust.Cui;
using UnityEngine;
namespace Oxide.Plugins
{
[Info("ShopUI", "RustPluginGenerator", "1.0.0")]
[Description("Opens a small shop panel when a player types /shop.")]
public class ShopUI : RustPlugin
{
private const string MainPanel = "ShopUI.Main";
private const string ItemsPanel = "ShopUI.Items";
private void Unload()
{
foreach (var player in BasePlayer.activePlayerList)
CuiHelper.DestroyUi(player, MainPanel);
}
[ChatCommand("shop")]
private void CmdShop(BasePlayer player, string command, string[] args)
{
if (player == null) return;
CuiHelper.DestroyUi(player, MainPanel);
// One container: root panel under Overlay first, then the child that uses it.
var c = new CuiElementContainer();
c.Add(new CuiPanel
{
Image = { Color = "0.1 0.1 0.1 0.95" },
RectTransform = { AnchorMin = "0.1 0.1", AnchorMax = "0.6 0.6" },
CursorEnabled = true
}, "Overlay", MainPanel);
c.Add(new CuiLabel
{
Text = { Text = "Items", FontSize = 14, Align = TextAnchor.MiddleCenter },
RectTransform = { AnchorMin = "0 0.8", AnchorMax = "1 1" }
}, MainPanel, ItemsPanel);
c.Add(new CuiPanel
{
Image = { Color = "0.2 0.2 0.2 0.9" },
RectTransform = { AnchorMin = "0 0 1 0.8" }
}, ItemsPanel);
CuiHelper.AddUi(player, c);
}
[ChatCommand("shopclose")]
private void CmdShopClose(BasePlayer player, string command, string[] args)
{
if (player == null) return;
CuiHelper.DestroyUi(player, MainPanel);
}
}
}FAQ
Why does the error appear for only some players?
CUI lives on the client. A player who relogged, died, or called by code that destroyed the UI no longer has the parent panel, so the next child-only update is rejected. Rebuild and resend the root panel for that player before sending children.
Should my panel parent be "Overlay" or "Hud"?
Use Overlay for interactive windows that need the cursor, and Hud for passive readouts. Both are always present on the client, so they are safe parents for your root panel. Do not attach children to a custom name you have not added yet.
Does adding the parent and child in one CuiElementContainer fix it?
Yes. Elements in a single container are applied in order, so if the parent panel element comes first with a name, the child that references that name resolves. The problem only occurs when the parent element is missing from what the client receives.
Why does the error survive an oxide.reload?
Reloading the server plugin does not clear the client UI tree. Call CuiHelper.DestroyUi for your named panels in Unload and in your open command, then rebuild. The server never sees this message — it is client-side only.
Different error?
Paste the full console output and get the cause and a fix in plain English.
Open the error explainerSkip the debugging
Generated plugins are compiled before you get them, and compiler errors are fixed automatically.
Generate a plugin2 free plugins a month, no card.
Last updated Oct 26, 2026.
Get plugins that compile first time
Generate