Fix "Plugin 'AutoBroadcast' is using the Lang API but has no messages registered" (Oxide)
Oxide prints this when your plugin calls lang.GetMessage for a key that was never registered, usually because LoadDefaultMessages does not exist or does not call lang.RegisterMessages. Register a defaults dictionary in LoadDefaultMessages (or call lang.RegisterMessages once before use) and every lookup resolves.
Plugin 'AutoBroadcast' is using the Lang API but has no messages registered
Why it happens
The message comes from Oxide's language layer. When a plugin asks Oxide to resolve a lang key, Oxide checks whether that plugin has any registered messages at all. If the plugin has never called lang.RegisterMessages, there is nothing to resolve against, so Oxide logs the warning once and the lookup returns nothing useful.
Common triggers:
- The plugin has a
Msghelper that callslang.GetMessage(key, this, userId)but noprotected override void LoadDefaultMessages()method. LoadDefaultMessagesexists but registers an empty dictionary, or registers keys with names that differ from the ones used at call sites.- Keys were registered in a
Init/Loadedhook that returns early (for example when a config check fails) before the registration line runs. - The plugin was copied from another plugin and the
LoadDefaultMessagesblock was dropped while theMsghelper remained.
The plugin keeps running; the warning is a signal that every player-facing string it sends is empty or missing.
How to fix it
- Add
protected override void LoadDefaultMessages()to the plugin class. - Inside it call
lang.RegisterMessages(new Dictionary<string, string> { ... }, this);with every key your code passes tolang.GetMessage. - Keep key names identical between the dictionary and call sites; a typo produces an empty string, not this warning, so check both lists.
- If the plugin registers messages conditionally, move the registration so it always runs on load, before any timer or command can call
Msg. - Optionally create
oxide/lang/en/<PluginName>.json; Oxide writes the defaults there on first run and lets you edit text without recompiling. Note Carbon usescarbon/lang/en/. - Confirm with
oxide.reload AutoBroadcast. A clean reload printsLoaded plugin AutoBroadcast v1.0.0 by RustPluginGeneratorand no Lang API line in the console oroxide/logs.
Before and after
using System.Collections.Generic;
using Oxide.Core;
using Oxide.Core.Plugins;
using UnityEngine;
namespace Oxide.Plugins
{
[Info("AutoBroadcast", "RustPluginGenerator", "1.0.0")]
[Description("Broadcasts a message to all online players on a timer")]
public class AutoBroadcast : RustPlugin
{
private Timer broadcastTimer;
private string Msg(string key, string userId = null, params object[] args)
{
return string.Format(lang.GetMessage(key, this, userId), args);
}
private void OnServerInitialized()
{
broadcastTimer = timer.Every(300f, Broadcast);
}
private void Broadcast()
{
if (BasePlayer.activePlayerList.Count == 0)
{
return;
}
Server.Broadcast(Msg("Broadcast", null, "Welcome to the server"));
}
private void Unload()
{
if (broadcastTimer != null)
{
broadcastTimer.Destroy();
}
}
}
}using System;
using System.Collections.Generic;
using Oxide.Core;
using Oxide.Core.Plugins;
using UnityEngine;
namespace Oxide.Plugins
{
[Info("AutoBroadcast", "RustPluginGenerator", "1.0.0")]
[Description("Broadcasts a message to all online players on a timer")]
public class AutoBroadcast : RustPlugin
{
private Timer broadcastTimer;
protected override void LoadDefaultMessages()
{
lang.RegisterMessages(new Dictionary<string, string>
{
["Broadcast"] = "{0}",
["NoPlayers"] = "Nobody is online to receive the broadcast."
}, this);
}
private string Msg(string key, string userId = null, params object[] args)
{
return string.Format(lang.GetMessage(key, this, userId), args);
}
private void OnServerInitialized()
{
broadcastTimer = timer.Every(300f, Broadcast);
}
private void Broadcast()
{
if (BasePlayer.activePlayerList.Count == 0)
{
return;
}
Server.Broadcast(Msg("Broadcast", null, "Welcome to the server"));
}
private void Unload()
{
if (broadcastTimer != null)
{
broadcastTimer.Destroy();
broadcastTimer = null;
}
}
}
}FAQ
Does this warning stop the plugin from working?
No. The plugin stays loaded and the hook or command still runs. The problem is that the lang lookup has no table to read from, so player-facing text is empty or falls back to the raw key. Fix the registration before players see blank chat lines.
I registered messages in Init and still see the warning. Why?
Check whether Init returns early (for example on a missing dependency) or runs after the first lookup. Move lang.RegisterMessages into LoadDefaultMessages, which Oxide calls during plugin load, and remove any duplicate registration from Init to avoid overwriting lang files.
Where do the lang files live?
Oxide writes defaults to oxide/lang/en/<PluginName>.json the first time the plugin registers messages. Carbon uses carbon/lang/en/<PluginName>.json. Editing that file changes text without recompiling; delete it to regenerate defaults after you add new keys.
Does calling lang.GetMessage from a static method cause this?
A static context cannot pass this, so the plugin instance is unknown and the registration lookup fails. Move the helper into the plugin class as an instance method, or store a static reference to the plugin instance and pass it to lang.GetMessage.
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