Skip to content
RustPluginGenerator
CS0051Oxide + Carbon

Fix CS0051: Inconsistent accessibility in Oxide plugins

CS0051 means a public method, property or constructor exposes a type that is not public, so callers outside the assembly could not name the parameter. Change the nested type to public, or make the method private.

Server console
Error while compiling StatsApi:
[1] Inconsistent accessibility: parameter type 'StatsApi.PlayerStats' is less accessible than method 'StatsApi.SaveStats(StatsApi.PlayerStats)' at 30:21

Why it happens

In C# an accessible member cannot advertise a parameter or return type that is less accessible than itself. Inside an Oxide plugin the usual trap is a nested helper class or struct (for example private class PlayerStats) while a matching method, property or constructor is declared public. StatsApi.SaveStats(StatsApi.PlayerStats) is public, but the nested PlayerStats type is private, so the compiler refuses with CS0051 and points at the method signature line. The same error appears when the nested type has no modifier at all: inside a class it defaults to private. A public property returning that nested type, or a public constructor taking it, triggers the identical message with property type or parameter type. Note that plugin classes themselves stay in the default internal visibility inside the Oxide.Plugins namespace; only the mismatch between two members' accessibility matters here.

How to fix it

  1. Read the message: it names both the member (SaveStats) and the type (StatsApi.PlayerStats).
  2. Open the plugin and find the nested type declaration.
  3. If code outside the plugin class never uses the type, add private or internal to the method or property (or lower it to a private helper) so the member is no more accessible than the type.
  4. If the method must stay public, mark the nested type public (or internal) so the accessibility matches: public class PlayerStats { ... }.
  5. Fix every other member that mentions the same type, since the compiler reports them one by one.
  6. Save the file and run oxide.reload StatsApi. Oxide compiles on save; a clean load prints Loaded plugin ... and no Error while compiling block. Inside namespace Oxide.Plugins the type Timer already resolves without a using directive.

Before and after

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

namespace Oxide.Plugins
{
    [Info("StatsApi", "RustPluginGenerator", "1.0.0")]
    [Description("Stores simple per-player statistics in oxide/data")]
    public class StatsApi : RustPlugin
    {
        private StatsFile data;

        private class StatsFile
        {
            public Dictionary<string, PlayerStats> Players = new Dictionary<string, PlayerStats>();
        }

        private class PlayerStats
        {
            public int Kills;
            public int Deaths;
        }

        private void OnServerInitialized()
        {
            data = Interface.Oxide.DataFileSystem.ReadObject<StatsFile>(Name) ?? new StatsFile();
        }

        public void SaveStats(PlayerStats stats)
        {
            if (stats == null) return;
            data.Players["last"] = stats;
            Interface.Oxide.DataFileSystem.WriteObject(Name, data);
        }

        [ChatCommand("stats")]
        private void CmdStats(BasePlayer player, string command, string[] args)
        {
            if (player == null) return;
            PlayerStats stats;
            if (!data.Players.TryGetValue(player.UserIDString, out stats))
            {
                stats = new PlayerStats();
                data.Players[player.UserIDString] = stats;
            }
            stats.Kills++;
            SaveStats(stats);
            SendReply(player, "Kills: " + stats.Kills + ", Deaths: " + stats.Deaths);
        }
    }
}
AfterFixed
using System;
using System.Collections.Generic;
using Oxide.Core;
using Oxide.Core.Plugins;

namespace Oxide.Plugins
{
    [Info("StatsApi", "RustPluginGenerator", "1.0.0")]
    [Description("Stores simple per-player statistics in oxide/data")]
    public class StatsApi : RustPlugin
    {
        private StatsFile data;

        private class StatsFile
        {
            public Dictionary<string, PlayerStats> Players = new Dictionary<string, PlayerStats>();
        }

        public class PlayerStats
        {
            public int Kills;
            public int Deaths;
        }

        private void OnServerInitialized()
        {
            data = Interface.Oxide.DataFileSystem.ReadObject<StatsFile>(Name) ?? new StatsFile();
        }

        private void SaveStats(PlayerStats stats)
        {
            if (stats == null) return;
            data.Players["last"] = stats;
            Interface.Oxide.DataFileSystem.WriteObject(Name, data);
        }

        [ChatCommand("stats")]
        private void CmdStats(BasePlayer player, string command, string[] args)
        {
            if (player == null) return;
            PlayerStats stats;
            if (!data.Players.TryGetValue(player.UserIDString, out stats))
            {
                stats = new PlayerStats();
                data.Players[player.UserIDString] = stats;
            }
            stats.Kills++;
            SaveStats(stats);
            SendReply(player, "Kills: " + stats.Kills + ", Deaths: " + stats.Deaths);
        }
    }
}

FAQ

Why does a nested class without any modifier cause CS0051?

Members of a class default to private, and that includes nested classes. A public method that takes that nested class as a parameter is more accessible than the type it exposes, so the compiler emits CS0051. Adding public to the nested class or private to the method resolves it.

Is this an Oxide or Carbon problem?

No. CS0051 is a plain C# compiler error produced by Roslyn. Oxide and Carbon only run the compiler and print its messages, which is why the fix is the same in both: align the accessibility of the member and the type it uses.

Do I need to make the plugin class public?

No. The plugin class itself is fine as declared. The mismatch is between the nested helper type and the member that exposes it. Changing the nested type to public or the member to private is enough; Oxide still finds the main class either way.

The error line number points to the method, not the class. Why?

The compiler reports the error where the inaccessible type is used in the signature, not where the type is declared. The message still names the type, so search the file for that name and adjust its declaration.

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