Skip to content
RustPluginGenerator
CS0161Oxide + Carbon

Fix CS0161: not all code paths return a value (Oxide)

CS0161 means your method is declared to return a value (for example a Canvas or object hook) but at least one path through the method reaches the closing brace without a return statement. Add the missing return, usually return null at the end of object-returning hooks like CanLootEntity.

Server console
Error while compiling LootBlocker:
[1] 'LootBlocker.CanLootEntity(BasePlayer, StorageContainer)': not all code paths return a value at 17:24

Why it happens

Oxide hook methods that decide something (CanLootEntity, CanUseItem, OnLootEntity, OnEntityTakeDamage filters, CanBuild) return an object, so the compiler requires every branch to end in a return. The common trigger is an early exit written as return; or a bare if block that never returns, and then no final return null;. In the reported case CanLootEntity(BasePlayer, StorageContainer) is declared returning object but the method ends after the permission check. The C# compiler stops at the first unconverted path and reports CS0161 with the method signature and the line/column of the closing brace, so one missing return hides nothing else. Oxide cannot load the plugin until this compiles, so the file disappears from the loaded plugin list.

How to fix it

  1. Look at the line and column in the message: at 14:24 points at the closing brace of the named method.
  2. Give every if that should deny an action an explicit return false; (or whatever the hook expects) instead of a bare return;.
  3. Add return null; at the very end of object-returning hooks to keep default game behaviour.
  4. For void hooks, remove the return type expectation entirely: void methods must not return a value; if you need to exit early use a plain return;.
  5. Save the file. Oxide recompiles automatically and prints Loaded plugin LootBlocker v1.0.0 by RustPluginGenerator. If a compile error remains, look at oxide/logs for the full Roslyn output with the CS code.
  6. Run oxide.reload LootBlocker from the server console to confirm it loads with no Error while compiling line.

Before and after

BeforeFails
using Oxide.Core.Plugins;
using UnityEngine;

namespace Oxide.Plugins
{
    [Info("LootBlocker", "RustPluginGenerator", "1.0.0")]
    [Description("Prevents players without permission from looting storage containers")]
    public class LootBlocker : RustPlugin
    {
        private const string PermBypass = "lootblocker.bypass";

        private void Init()
        {
            permission.RegisterPermission(PermBypass, this);
        }

        private object CanLootEntity(BasePlayer player, StorageContainer container)
        {
            if (player == null || container == null)
            {
                return null;
            }

            if (!permission.UserHasPermission(player.UserIDString, PermBypass))
            {
                player.ChatMessage("You are not allowed to loot this container.");
                return false;
            }
        }
    }
}
AfterFixed
using Oxide.Core.Plugins;
using UnityEngine;

namespace Oxide.Plugins
{
    [Info("LootBlocker", "RustPluginGenerator", "1.0.0")]
    [Description("Prevents players without permission from looting storage containers")]
    public class LootBlocker : RustPlugin
    {
        private const string PermBypass = "lootblocker.bypass";

        private void Init()
        {
            permission.RegisterPermission(PermBypass, this);
        }

        private object CanLootEntity(BasePlayer player, StorageContainer container)
        {
            if (player == null || container == null)
            {
                return null;
            }

            if (!permission.UserHasPermission(player.UserIDString, PermBypass))
            {
                player.ChatMessage("You are not allowed to loot this container.");
                return false;
            }

            return null;
        }
    }
}

FAQ

Which Oxide hooks return object and need return null?

Hooks whose name starts with Can (for example CanLootEntity, CanUseItem, CanBuild, CanPickupEntity) are the usual suspects. Declaring them private object CanLootEntity(BasePlayer player, StorageContainer container) is fine, but every branch and the end of the method must return a value. return null means 'use the game default'.

The method already has a return inside an if. Why is CS0161 still raised?

The compiler checks all paths. If the if condition is false, execution continues past the block to the closing brace without returning. Add return null; after the if block so the fall-through path is covered.

Does CS0161 stop the whole plugin folder from loading?

Only the failing file is dropped from the compile batch; other plugins still load. Oxide prints Error while compiling LootBlocker: with the numbered Roslyn message, and LootBlocker is not available until the file compiles. Saving the .cs file triggers a reload attempt.

What does CS0161 look like in the Carbon console?

Carbon loads the same Oxide plugin file and reports the same Roslyn diagnostic, but its console format differs: it includes the CS code (CS0161) alongside the message, so you can search this page by the code rather than the full Oxide prefix.

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