Fix OpenClaw Agent Not Responding to Discord Messages
Fix OpenClaw Agent Not Responding to Discord Messages

You set up your OpenClaw agent, connected it to Discord, watched it respond to a test message, felt that brief rush of satisfaction β and then it justβ¦ stopped. Messages come in, your agent sits there like a brick. No errors in the console. No crash. Just silence.
I've been there. Multiple times. And after helping a bunch of people debug this exact issue in the OpenClaw community, I can tell you: it's almost always one of about six things. The good news is that every single one of them is fixable, usually in under ten minutes.
Let's walk through them.
First: Confirm the Agent Is Actually Running
This sounds obvious, but you'd be surprised how often the issue is that the agent process silently died and nobody noticed. OpenClaw agents run as persistent processes, and if something in your environment hiccups β a memory spike, a dropped SSH session, a Docker container restart β the process can terminate without any dramatic error message.
Check the basics:
# See if your agent process is alive
ps aux | grep openclaw
# Or if you're using OpenClaw's built-in process manager
openclaw status --agent discord-bot
If you get nothing back, your agent isn't running. Restart it:
openclaw start --agent discord-bot --config ./config.yaml
But here's the thing β just restarting isn't enough if you don't know why it stopped. Check the logs:
openclaw logs --agent discord-bot --tail 100
Look for anything with ERROR or FATAL in it. If the agent ran out of memory, you'll usually see an OOMKilled message (especially in Docker). If it was a crash, there should be a stack trace.
Pro tip: Always run your agents with OpenClaw's built-in watchdog enabled:
agent = OpenClawAgent(
watchdog=True,
auto_restart=True,
max_restarts=5,
restart_cooldown=30 # seconds between restarts
)
This way, if your agent dies, it comes back automatically. No more waking up to find your bot has been offline for eight hours.
The Most Common Culprit: Discord Gateway Disconnects
This is, by far, the number one reason OpenClaw agents stop responding to Discord messages. And it's sneaky because your agent process is still running β it just lost its WebSocket connection to Discord's gateway and didn't reconnect.
Discord's gateway connections are fragile. They require regular heartbeats, and if your agent misses one (because it was busy processing a long task, or because of a brief network blip), Discord drops the connection. If your reconnection logic isn't solid, your agent keeps running but never receives another message.
Here's what a properly configured Discord connection looks like in OpenClaw:
from openclaw import OpenClawAgent
from openclaw.channels import DiscordChannel
discord = DiscordChannel(
token="YOUR_BOT_TOKEN",
gateway_intents=["messages", "message_content", "guilds"],
reconnect=True,
reconnect_attempts=10,
heartbeat_timeout=60,
connection_timeout=30
)
agent = OpenClawAgent(
channels=[discord],
verbose=True # You want to see connection events
)
The critical settings people miss:
reconnect=Trueβ This isn't always the default. Without it, a single dropped connection means permanent silence.gateway_intentsβ Discord requires you to explicitly declare which events you want. If you're missingmessage_content, your agent connects fine but literally never sees message content. It's like showing up to a meeting with noise-canceling headphones on.heartbeat_timeoutβ If your agent is doing heavy processing (like running an LLM inference that takes 30+ seconds), it can miss Discord's heartbeat window. Bumping this up gives you breathing room.
To verify your connection is healthy right now:
# Check connection state
status = agent.channel_status("discord")
print(status)
# Should show: {"connected": True, "latency_ms": 45, "last_heartbeat": "2s ago"}
If connected shows False, there's your problem.
The Intent Problem (This One Burns Everyone)
I'm giving this its own section because it's responsible for probably 30% of all "my agent isn't responding" posts I've seen.
In October 2022, Discord made the message_content intent privileged. That means you need to explicitly enable it in both your Discord Developer Portal and your code. If you don't, your bot can see that a message was sent, but the actual content arrives as an empty string. Your agent receives the event, tries to process an empty message, and either silently discards it or sends back a confused non-response.
Step 1: Go to the Discord Developer Portal, select your bot, go to the "Bot" tab, and under "Privileged Gateway Intents," make sure Message Content Intent is toggled ON.
Step 2: Make sure your code requests it:
discord = DiscordChannel(
token="YOUR_BOT_TOKEN",
gateway_intents=["messages", "message_content", "guilds"]
# ^^^^^^^^^^^^^^^^
# This one. Right here. Don't forget it.
)
Step 3: Verify the message content is actually coming through by turning on verbose logging:
agent = OpenClawAgent(
channels=[discord],
verbose=True,
log_level="DEBUG"
)
# In your logs, you should see:
# [DEBUG] Discord message received: {"content": "hello bot", "author": "user#1234"}
# NOT:
# [DEBUG] Discord message received: {"content": "", "author": "user#1234"}
If you see empty content strings, the intent isn't enabled properly. Go back to the portal and double-check.
Your Agent Is Responding... Just Not Where You Think
Another common scenario: the agent is processing messages and generating responses, but the response never makes it back to the Discord channel. This usually comes down to one of three things:
1. Channel permissions. Your bot might not have permission to send messages in the channel where users are talking to it. Check that the bot role has Send Messages and Read Message History permissions in that specific channel.
2. Response routing misconfiguration. If you've set up multiple channels or custom response handlers, the response might be going somewhere else:
# Wrong: Response goes to a hardcoded channel
agent = OpenClawAgent(
response_channel="general" # Always responds in #general
)
# Right: Response goes back to the channel where the message came from
agent = OpenClawAgent(
response_routing="reply_in_context" # Responds where the message was sent
)
3. The response is too long. Discord has a 2,000-character limit per message. If your OpenClaw agent generates a response longer than that and you don't have chunking enabled, the API call to send the message fails silently (or throws an error that gets swallowed):
discord = DiscordChannel(
token="YOUR_BOT_TOKEN",
max_message_length=2000,
auto_chunk=True, # Splits long responses into multiple messages
chunk_delimiter="\n\n" # Splits at paragraph breaks for readability
)
The Silent Killer: Unhandled Exceptions in Skills
This is the one that drove me crazy for the longest time. Your agent receives a message, starts processing it, a skill throws an exception, and because the exception isn't caught properly, the agent's message handler dies silently. The agent stays connected, keeps receiving messages, but every single one hits the same uncaught exception and gets dropped.
OpenClaw's execution trace is your best friend here:
agent = OpenClawAgent(
verbose=True,
on_error="log_and_respond", # Don't silently swallow errors
error_message="Something went wrong processing your request. Let me try again."
)
With on_error="log_and_respond", instead of silent failure, the agent will:
- Log the full error with stack trace
- Send a user-friendly error message back to Discord
- Continue processing future messages normally
You can also add circuit breakers to prevent a broken skill from taking down your whole agent:
from openclaw.skills import WebSearchSkill
agent = OpenClawAgent(
skills=[
WebSearchSkill(
max_retries=3,
timeout=15,
fallback="I wasn't able to search the web right now, but here's what I know..."
)
]
)
To identify which skill is failing, check the execution trace:
# After a failed interaction, pull the trace
trace = agent.last_execution_trace()
print(trace)
# Output:
# Step 1: Received message "what's the weather in NYC" β
# Step 2: Intent classification β "weather_query" β
# Step 3: Executing WebSearchSkill β FAILED (TimeoutError after 15s)
# Step 4: Fallback response sent β
Without this visibility, you're debugging blind. With it, you can pinpoint the exact skill and the exact failure in seconds.
Rate Limits and Token Budget Exhaustion
If your agent worked fine for a while and then stopped responding, you might have hit a rate limit β either from Discord's API or from your LLM provider.
Discord rate limits are per-channel and per-guild. If your agent is in a busy server trying to respond to every message, it can get rate-limited fast. OpenClaw handles this with built-in rate limit awareness:
discord = DiscordChannel(
token="YOUR_BOT_TOKEN",
rate_limit_handling="queue", # Queue messages instead of dropping them
max_queue_size=50,
response_delay=1.0 # Minimum seconds between responses
)
On the LLM side, if you set a token budget and it's exhausted, your agent will stop generating responses:
agent = OpenClawAgent(
budget={
"max_tokens": 100000,
"max_cost_usd": 10.00,
"on_budget_exceeded": "notify_and_pause" # Don't just silently stop
}
)
# Check current usage
print(agent.budget_status())
# {"tokens_used": 98500, "cost_usd": 9.72, "remaining_pct": 1.5}
If on_budget_exceeded is set to the default (which in some versions is "silent_stop"), your agent will just stop responding with no indication why. Always set it to "notify_and_pause" or "notify_and_continue" so you at least know what happened.
The Nuclear Option: Full Reset and Rebuild
If you've checked everything above and your agent still isn't responding, it's time for a clean slate. Sometimes config drift, cached state, or corrupted session data is the problem, and the fastest fix is a fresh start:
# Stop the agent
openclaw stop --agent discord-bot
# Clear cached state
openclaw clear-cache --agent discord-bot
# Validate your config
openclaw validate --config ./config.yaml
# Start fresh
openclaw start --agent discord-bot --config ./config.yaml --verbose
The validate command is underused and incredibly helpful. It checks your config against the current OpenClaw schema, verifies your API keys are valid, tests your Discord bot token, and confirms your skills are properly configured β all before you start the agent.
The "I Don't Want to Debug All This Manually" Option
Look, I just walked you through six different failure modes, and there are honestly more edge cases I didn't cover. If you're setting up an OpenClaw Discord agent for the first time and you'd rather skip the part where you discover each of these issues through painful trial and error, Felix's OpenClaw Starter Pack on Claw Mart is genuinely worth the $29.
It includes pre-configured skills with all the error handling, reconnection logic, rate limit management, and budget controls already set up. The Discord channel configuration comes with the correct intents, auto-chunking, and proper response routing out of the box. I've seen people go from "nothing works" to "fully functional Discord agent" in about fifteen minutes with it, versus the hours (or days) it can take to configure everything from scratch and debug each issue as you hit it.
It's not magic β it's the same OpenClaw configuration you'd write yourself, just done by someone who's already hit every pothole on the road and filled them in for you.
Prevention: A Healthy Agent Checklist
Once you get your agent responding again, set yourself up so this doesn't happen again. Here's what I run on all my OpenClaw Discord agents:
agent = OpenClawAgent(
# Connection resilience
channels=[
DiscordChannel(
token=BOT_TOKEN,
gateway_intents=["messages", "message_content", "guilds"],
reconnect=True,
reconnect_attempts=10,
rate_limit_handling="queue"
)
],
# Process resilience
watchdog=True,
auto_restart=True,
# Error handling
on_error="log_and_respond",
verbose=True,
log_level="INFO", # DEBUG when actively troubleshooting
# Budget protection
budget={
"max_cost_usd": 20.00,
"on_budget_exceeded": "notify_and_pause"
},
# Performance
timeout=30,
max_retries=3,
response_routing="reply_in_context",
# Observability
health_check=True,
health_check_interval=60 # Ping every 60 seconds
)
The health_check option is the secret weapon. It runs a lightweight self-diagnostic every 60 seconds, checking that the Discord connection is alive, the LLM provider is reachable, and all skills are functional. If anything fails, it logs a warning and attempts auto-recovery before your users even notice.
Next Steps
If your agent is currently not responding:
- Check if the process is running (
openclaw status) - Check the logs for errors (
openclaw logs) - Verify Discord intents are enabled (Developer Portal + code)
- Confirm channel permissions for your bot
- Look at the execution trace for skill failures
- Check your budget status
Nine times out of ten, it's the intents or the gateway disconnect. Start there.
And if you're building a new agent from scratch, save yourself the headache β start with a known-good configuration (whether that's Felix's Starter Pack or a tested config from the OpenClaw community), verify it works, and then start customizing. Building from zero and debugging connection issues simultaneously is a miserable experience. Don't do that to yourself.
Your agent wants to respond. It just needs you to clear the path.
Recommended for this post
