Skip to content
RustPluginGenerator
CS0128Oxide + Carbon

Fix CS0128: a local variable named 'player' is already defined (Oxide)

CS0128 means the same local variable name is declared twice in one method scope. In Oxide plugins this usually happens when you declare a variable that already exists as a hook parameter, such as `BasePlayer player` inside OnEntityDeath. Rename or reuse the existing variable.

Server console
Error while compiling DamageLogger:
[1] A local variable or function named 'victim' is already defined in this scope at 30:24

Why it happens

Every hook method in an Oxide plugin declares its parameters, and those parameters are local variables inside the method. If the body redeclares one of them with the same type, the C# compiler reports CS0128 on the second declaration. Typical triggers:

  • A hook already gives you BasePlayer player (or attacker, entity, victim) and the body starts with BasePlayer player = ... to look something up again.
  • Two blocks in the same method, or code pasted from another plugin, each declare var target or var item.
  • A helper variable in OnServerInitialized repeats a variable you already created at the top of the method.

The compiler stops at the second declaration, so the plugin is removed from the batch and not loaded until the name is fixed. The console line shows the line and column of the duplicate, not the original.

How to fix it

  1. Read the position after at in the console line (for example 28:17): that is where the duplicate is declared.
  2. Check the hook signature. If the parameter is already BasePlayer player, do not declare it again — just use it, or reuse an existing object.
  3. If you need a second value, give it a distinct name such as victimPlayer, cachedPlayer or owner.
  4. Delete the redundant declaration and assign into the existing variable instead of using its type name.
  5. Save the file (auto reload) or run oxide.reload DamageLogger. A successful load prints Loaded plugin Damage Logger v1.0.0 by RustPluginGenerator and no Error while compiling line.

If you need to keep the value after the hook returns, store what you need (id, name) rather than re-declaring the hook parameter.

Before and after

BeforeFails
using System.Collections.Generic;
using Oxide.Core;
using UnityEngine;

namespace Oxide.Plugins
{
    [Info("Damage Logger", "RustPluginGenerator", "1.0.0")]
    [Description("Logs the last damage a player takes before dying")]
    public class DamageLogger : RustPlugin
    {
        private readonly Dictionary<ulong, string> lastHit = new Dictionary<ulong, string>();

        private void OnEntityTakeDamage(BaseCombatEntity entity, HitInfo info)
        {
            if (entity == null || info == null) return;

            BasePlayer player = entity as BasePlayer;
            if (player == null) return;

            string source = info.InitiatorPlayer != null ? info.InitiatorPlayer.displayName : "environment";
            string type = info.damageTypes.GetMajorityDamageType().ToString();
            lastHit[player.userID.Get()] = source + " (" + type + ")";
        }

        private void OnPlayerDeath(BasePlayer player, HitInfo info)
        {
            if (player == null) return;

            BasePlayer victim = player as BasePlayer;
            BasePlayer victim = player as BasePlayer;

            string last;
            if (lastHit.TryGetValue(victim.userID.Get(), out last))
            {
                Puts(victim.displayName + " died, last damage from: " + last);
                lastHit.Remove(victim.userID.Get());
            }
        }
    }
}
AfterFixed
using System.Collections.Generic;
using Oxide.Core;
using UnityEngine;

namespace Oxide.Plugins
{
    [Info("Damage Logger", "RustPluginGenerator", "1.0.0")]
    [Description("Logs the last damage a player takes before dying")]
    public class DamageLogger : RustPlugin
    {
        private readonly Dictionary<ulong, string> lastHit = new Dictionary<ulong, string>();

        private void OnEntityTakeDamage(BaseCombatEntity entity, HitInfo info)
        {
            if (entity == null || info == null) return;

            BasePlayer player = entity as BasePlayer;
            if (player == null) return;

            string source = info.InitiatorPlayer != null ? info.InitiatorPlayer.displayName : "environment";
            string type = info.damageTypes.GetMajorityDamageType().ToString();
            lastHit[player.userID.Get()] = source + " (" + type + ")";
        }

        private void OnPlayerDeath(BasePlayer player, HitInfo info)
        {
            if (player == null) return;

            string last;
            if (lastHit.TryGetValue(player.userID.Get(), out last))
            {
                Puts(player.displayName + " died, last damage from: " + last);
                lastHit.Remove(player.userID.Get());
            }
        }
    }
}

FAQ

Does the error point at the first or second declaration?

The second one. The console shows <message> at <line>:<column> for the declaration the compiler rejected, so the name already exists earlier in the same method — often in the hook parameter list, which is not on that line.

Why does the plugin disappear after this error?

Oxide removes a file that fails to compile from the batch and compiles the rest, so the plugin is not loaded while the error is present. Fixing the name and saving the .cs file triggers a reload.

Can I just delete the second variable and keep the first one?

Only if the two hold the same thing. If the second is a different value (for example another player), a new distinct name is needed; otherwise you silently swap values.

Does Carbon report this differently?

Carbon loads the same file and reports CS0128 too, but prints the CS code with its own format. The fix is identical: remove the duplicate local name.

Different error?

Paste the full console output and get the cause and a fix in plain English.

Open the error explainer

Skip the debugging

Generated plugins are compiled before you get them, and compiler errors are fixed automatically.

Generate a plugin

2 free plugins a month, no card.

Last updated Oct 26, 2026.

Get plugins that compile first time

Generate