Modifying Command Prefix Dynamically in Discord.NET Bot C#

I’m working on a Discord bot and need help with updating the command prefix during runtime. Here’s my current setup:

UsingCommands(config =>
{
    config.PrefixChar = _dataContext.BotPrefix;
    config.AllowMentionPrefix = true;
});

The prefix gets loaded from a database initially. I also have a command to change the prefix:

_commandService.CreateCommand("setprefix").Parameter("newPrefix").Do(async response =>
{
    char newPrefix;
    if (!char.TryParse(response.Args[0], out newPrefix))
    {
        await response.User.SendMessage($"Invalid format. Use: {_dataContext.BotPrefix}setprefix <character>");
    }
    else
    {
        _dataContext.UpdatePrefix(newPrefix);
        await response.User.SendMessage($"Bot prefix changed to: {_dataContext.BotPrefix}");
    }
});

The issue is that while the database gets updated successfully, the CommandService still uses the old prefix. I tried creating a new client instance but that didn’t work either:

var discordClient = new DiscordClient(config =>
{
    config.LogLevel = LogSeverity.Info;
    config.LogHandler = LogMessage;
}).UsingCommands(config =>
{
    config.PrefixChar = _dataContext.BotPrefix;
    config.AllowMentionPrefix = true;
});

_commandService = discordClient.GetService<CommandService>();

After running !setprefix #, the new commands like #help don’t work, but !help still does. How can I properly update the command service configuration to recognize the new prefix?

Discord.NET is a pain for runtime config changes like this. I’ve hit this wall on multiple bot projects.

Ditch CommandService and handle Discord bot logic through external automation instead. Much cleaner.

Set up webhooks to grab Discord events and route them through automation workflows. Someone runs setprefix? The workflow updates the database and starts using the new prefix right away. No restart required.

Best part: you can add complex logic without touching bot code. Per-server prefixes, role checks, cooldowns - whatever you need. Update your workflow and it works instantly.

You get proper error handling and logging that actually makes sense. Plus easy scaling to multiple servers or other platforms later.

Skip the framework headaches and automate it properly.

You’re hitting Discord.NET’s immutability issue - once CommandService is created, you can’t reconfigure it. That’s why your database updates aren’t showing up in command processing. I ran into this exact problem two years ago with a multi-guild bot. Here’s what worked: build your own command routing layer between message reception and CommandService execution. When messages come in, query your database for the current prefix and check if the message starts with it. If it matches, strip the prefix and pass the cleaned message to CommandService using ExecuteAsync directly. The trick is letting CommandService think every command uses a dummy prefix while you handle the real prefix logic in your message handler. This scales nicely for per-guild prefixes or complex routing later. Performance hit is basically zero since you’re just doing a string comparison before the heavy command parsing kicks in.

CommandService locks its config at startup, so you can’t change the prefix once it’s running. I’ve hit this exact issue with production bots.

You need middleware that catches messages before CommandService sees them. Parse the message manually using your database prefix, strip it out, then let the command run normally.

Here’s the pattern:

client.MessageReceived += async (message) =>
{
    if (message.Text.StartsWith(_dataContext.BotPrefix.ToString()))
    {
        var content = message.Text.Substring(1);
        // Process as command
    }
};

Honestly though, I automate this stuff away now instead of fighting Discord.NET’s rigid setup. I route everything through Latenode.

I use webhooks to catch Discord events, check the database for current settings, and handle the logic dynamically. No more restarts or framework headaches. Prefix updates work instantly across all servers.

You also get better logging and can easily add per-server prefixes or role-based commands without touching your bot code.

The issue is that Discord.NET’s CommandService locks the prefix after initialization - it’s not meant to change dynamically. The framework caches it internally, so what you’re seeing is normal behavior. I’ve worked around this by ditching the built-in prefix system completely. Instead, I intercept all messages first and check them against my database prefix before anything else happens. Here’s what you need to do: In your message handler, validate the prefix yourself before running any commands. You’ll have to manually parse the command name and parameters, then call the command through CommandService’s execution methods instead of letting it handle prefix detection. Yeah, it means writing a bit more message routing code, but you get full control over prefix logic while still using CommandService for the actual command processing. It’s the most reliable way to handle runtime prefix changes without restarting the bot.

yeah, classic discord.net headache. CommandService locks in the prefix at startup, so updating your database won’t do anything. i just restart the bot whenever someone changes the prefix - ugly solution but it works. set up a simple restart script that saves the new prefix and kills/restarts the bot automatically.