Fix CS0019: Operator '==' cannot be applied to operands of type 'NetworkableId' and 'ulong' (Oxide)
CS0019 here means you compared an entity's net.ID (a NetworkableId struct) directly against a ulong. Compare net.ID.Value instead, which is the actual ulong network id.
Error while compiling EntityOwnerCheck: [1] Operator '==' cannot be applied to operands of type 'NetworkableId' and 'ulong' at 41:21
Why it happens
In Rust, BaseNetworkable.net.ID is of type NetworkableId (a wrapper struct), not a ulong. C# does not define an equality operator between NetworkableId and ulong, so any entity.net.ID == someUlong or entity.net.ID != someUlong expression fails with CS0019. This shows up in plugins that store ids as ulong (in data files, config, team members, permission strings, OwnerID, buildingID, player.userID) and then try to compare them to an entity's network id. The same error appears when the left side is the ulong and the right side is net.ID, or when you compare a NetworkableId to an int literal or an Item's parent/entityOwner id. The compiler line points at the exact column where the == sits, which is why the message names NetworkableId and ulong.
How to fix it
- Find every comparison that involves
.net.IDin the plugin (search fornet.ID). - If you have the entity and want its numeric id, read
entity.net.ID.Value. That is theulongyou can store, log and compare. - Rewrite
entity.net.ID == storedIdasentity.net.ID.Value == storedId. The same applies to!=,HashSet<ulong>.Containsand dictionary lookups keyed by ulong. - When you only have the ulong and need the entity, iterate
BaseNetworkable.serverEntitiesand compare.net.ID.Value, or look it up withBaseNetworkable.serverEntities.Find(new NetworkableId(id)). - Save the file and reload with
oxide.reload EntityOwnerCheck. Confirm the console printsLoaded plugin EntityOwnerCheck v1.0.0 by RustPluginGeneratorand that no newError while compiling EntityOwnerCheckline appears.
Before and after
using Oxide.Core.Plugins;
using UnityEngine;
namespace Oxide.Plugins
{
[Info("EntityOwnerCheck", "RustPluginGenerator", "1.0.0")]
[Description("Checks whether a building block belongs to a stored network id")]
public class EntityOwnerCheck : RustPlugin
{
private ulong trackedId;
[ChatCommand("track")]
private void CmdTrack(BasePlayer player, string command, string[] args)
{
if (player == null)
return;
var entity = player.GetActiveItem()?.GetHeldEntity();
if (entity == null)
{
SendReply(player, "Hold an entity item first.");
return;
}
trackedId = entity.net.ID.Value;
SendReply(player, "Tracking entity " + trackedId);
}
[ChatCommand("check")]
private void CmdCheck(BasePlayer player, string command, string[] args)
{
if (player == null)
return;
foreach (var networkable in BaseNetworkable.serverEntities)
{
var block = networkable as BuildingBlock;
if (block == null)
continue;
if (block.net.ID == trackedId)
{
SendReply(player, "Found the tracked block at " + block.transform.position);
return;
}
}
SendReply(player, "Tracked block not found.");
}
}
}using Oxide.Core.Plugins;
using UnityEngine;
namespace Oxide.Plugins
{
[Info("EntityOwnerCheck", "RustPluginGenerator", "1.0.0")]
[Description("Checks whether a building block belongs to a stored network id")]
public class EntityOwnerCheck : RustPlugin
{
private ulong trackedId;
[ChatCommand("track")]
private void CmdTrack(BasePlayer player, string command, string[] args)
{
if (player == null)
return;
var entity = player.GetActiveItem()?.GetHeldEntity();
if (entity == null)
{
SendReply(player, "Hold an entity item first.");
return;
}
trackedId = entity.net.ID.Value;
SendReply(player, "Tracking entity " + trackedId);
}
[ChatCommand("check")]
private void CmdCheck(BasePlayer player, string command, string[] args)
{
if (player == null)
return;
foreach (var networkable in BaseNetworkable.serverEntities)
{
var block = networkable as BuildingBlock;
if (block == null)
continue;
if (block.net.ID.Value == trackedId)
{
SendReply(player, "Found the tracked block at " + block.transform.position);
return;
}
}
SendReply(player, "Tracked block not found.");
}
}
}FAQ
Why is net.ID not a ulong?
Facepunch wraps network ids in a NetworkableId struct so ids carry a generation counter and are not plain integers. The raw number is exposed as net.ID.Value. Store and compare the Value field, never the struct itself.
Can I use NetworkableId as a dictionary key?
Yes, NetworkableId is a struct with value equality and works as a Dictionary<NetworkableId, T> key. Mixing it with Dictionary<ulong, T> is what triggers CS0019 or CS1503; pick one and stay consistent across the file.
The comparison is against a stored ulong and CS0019 is gone but the check never matches.
Verify that the stored value came from net.ID.Value and not from OwnerID or buildingID. Those are different concepts: OwnerID is a player or entity owner, while net.ID.Value identifies the network entity itself.
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