Fix CS0111: type already defines a member with the same parameter types (Oxide)
The plugin declares two methods with the same name and the same parameter types, so the compiler cannot tell them apart. Merge the bodies into one method, or delete the duplicate if it is an accidental copy.
Error while compiling DeathNotes: [1] Type 'DeathNotes' already defines a member called 'OnEntityDeath' with the same parameter types at 42:22
Why it happens
C# allows overloads only when the parameter types differ. Two OnEntityDeath(BasePlayer, BaseCombatEntity) methods in the same class are not an overload, they are a conflict, and Roslyn reports CS0111 on the second one. In Oxide plugins this usually comes from pasting a hook from another plugin or from a chat log without removing the version you already had. It also happens when someone splits a hook into two halves (OnEntityDeath for PvP and a second OnEntityDeath for NPCs) instead of branching inside one method, or when a hook is declared in the main plugin class and again in a nested helper class that derives from it with the same signature. Oxide does not merge methods: it looks for one method per hook name and invokes it, so the duplicate must be resolved in source before the plugin can load.
How to fix it
- Look at the line number in
Error while compiling <Name>:- the message points at the second declaration. - Open the file and search for the hook name (for example
OnEntityDeath). You will find two methods with identical parameter types. - Decide which body you keep: if both do useful work, copy the statements from the second into the first, in the order you want them to run. Delete the second method entirely.
- If the two bodies handle different cases, keep one method and put an
ifon the case inside it (victim is NPC vs player, killer is null vs not). - Save the file. Oxide recompiles automatically and prints
Loaded plugin <Title> v<Version> by <Author>when it succeeds. To force it, runoxide.reload DeathNotesin the server console. A remaining CS0111 means a third copy exists - search the whole file, not just the visible region.
Before and after
using System.Collections.Generic;
using Oxide.Core;
namespace Oxide.Plugins
{
[Info("DeathNotes", "RustPluginGenerator", "1.0.0")]
[Description("Broadcasts a short message when a player kills another player")]
public class DeathNotes : RustPlugin
{
private const string PermBroadcast = "deathnotes.broadcast";
protected override void LoadDefaultMessages()
{
lang.RegisterMessages(new Dictionary<string, string>
{
["Killed"] = "{0} killed {1} with {2}",
["KilledNpc"] = "{0} killed an NPC"
}, this);
}
private string Msg(string key, string userId = null, params object[] args)
{
return string.Format(lang.GetMessage(key, this, userId), args);
}
private void OnEntityDeath(BaseCombatEntity entity, HitInfo info)
{
if (entity == null || info == null)
{
return;
}
var victim = entity as BasePlayer;
if (victim == null || info.InitiatorPlayer == null || info.InitiatorPlayer == victim)
{
return;
}
Server.Broadcast(Msg("Killed", null, info.InitiatorPlayer.displayName, victim.displayName));
}
private void OnEntityDeath(BaseCombatEntity entity, HitInfo info)
{
if (entity == null || info == null || entity is BasePlayer)
{
return;
}
var killer = info.InitiatorPlayer;
if (killer == null || killer == entity)
{
return;
}
Server.Broadcast(Msg("KilledNpc", null, killer.displayName));
}
}
}using System.Collections.Generic;
using Oxide.Core;
using UnityEngine;
namespace Oxide.Plugins
{
[Info("DeathNotes", "RustPluginGenerator", "1.0.0")]
[Description("Broadcasts a short message when a player kills another player")]
public class DeathNotes : RustPlugin
{
private const string PermBroadcast = "deathnotes.broadcast";
protected override void LoadDefaultMessages()
{
lang.RegisterMessages(new Dictionary<string, string>
{
["Killed"] = "{0} killed {1} with {2}",
["KilledNpc"] = "{0} killed an NPC"
}, this);
}
private string Msg(string key, string userId = null, params object[] args)
{
return string.Format(lang.GetMessage(key, this, userId), args);
}
private void OnEntityDeath(BaseCombatEntity entity, HitInfo info)
{
if (entity == null || info == null)
{
return;
}
var killer = info.InitiatorPlayer;
if (killer == null || killer == entity)
{
return;
}
var victim = entity as BasePlayer;
if (victim != null)
{
string weapon = "unknown";
if (info.Weapon != null)
{
var item = info.Weapon.GetItem();
if (item != null && item.info != null)
{
weapon = item.info.displayName.english;
}
}
Server.Broadcast(Msg("Killed", null, killer.displayName, victim.displayName, weapon));
return;
}
Server.Broadcast(Msg("KilledNpc", null, killer.displayName));
}
}
}FAQ
Does Oxide support hook overloads with different parameter types?
Yes in the sense that Oxide picks the method whose declared parameter types match the arguments it passes. Two methods with the same name but genuinely different parameter types compile, but only the one matching the call is invoked. If both declare the same types, the compiler stops you first with CS0111.
Can I keep two OnEntityDeath bodies by putting them in different classes?
Only if the second class is not itself a loaded RustPlugin. Two plugin classes in one file is a separate problem. Keep a single hook in the plugin class and move reusable logic into a private helper method that the hook calls.
Why does Carbon show the error differently?
Carbon prints the CS code and the surrounding source line with its own format instead of the numbered [1] ... at line:column form. The compiler rule is the same: duplicate signature in the same type. Fix the source the same way and reload.
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