Discord Channel Reports as 'Not Configured, Disabled' After Upgrade
Regression bug where Discord channel configuration is not recognized after upgrading OpenClaw, causing the channel to report as 'installed, not configured, disabled' despite valid token configuration.
π Symptoms
Technical Manifestations
After upgrading OpenClaw from v2026.3.24 to 2026.5.7, the Discord channel reports an unexpected disabled state despite valid configuration.
CLI Output Example
$ openclaw channels list --all
Discord: installed, not configured, disabled
slack: installed, configured, enabled
telegram: installed, configured, enabled
Gateway Startup Log
$ openclaw gateway start
[INFO] OpenClaw Gateway v2026.5.7 starting...
[INFO] Loading configuration from /etc/openclaw/config.json
[INFO] Configuration loaded successfully
[INFO] Discord channel: disabled (not configured)
[INFO] Gateway started on port 3000
Configuration File Present
$ cat /etc/openclaw/config.json | jq '.channels.discord'
{
"enabled": true,
"token": "REDACTED_DISCORD_BOT_TOKEN",
"groupPolicy": "allowlist",
"guilds": {
"xxx": {
"requireMention": true,
"users": [
"xxx"
]
}
}
}
Environment Variable Check
$ env | grep -i discord
# No Discord-related environment variables set
$ env | grep -i OPENCLAW
OPENCLAW_CONFIG_PATH=/etc/openclaw/config.json
Affected Versions
| Version | Status |
|---|---|
v2026.3.24 | Works correctly |
2026.5.x | Regression introduced |
2026.5.7 | Confirmed affected |
π§ Root Cause
Primary Root Cause: Configuration Schema Migration
The regression stems from a configuration schema change introduced between v2026.3.24 and 2026.5.x. The Discord channel configuration validation logic was refactored, introducing stricter validation that rejects configurations using the legacy schema format.
Technical Analysis
1. Token Field Renaming
The internal configuration key for the Discord bot token was changed from token to botToken in the schema validation layer:
javascript // Legacy schema (v2026.3.24) const discordSchema = { token: { type: ‘string’, required: true }, groupPolicy: { type: ‘string’, default: ‘allowlist’ } };
// New schema (v2026.5.x) const discordSchema = { botToken: { type: ‘string’, required: true }, groupPolicy: { type: ‘string’, default: ‘allowlist’ } };
2. Configuration Resolution Order Change The configuration loader now checks environment variables with higher priority, but the environment variable names were also updated:
| Legacy Env Var | New Env Var |
|---|---|
DISCORD_TOKEN | OPENCLAW_DISCORD_BOT_TOKEN |
DISCORD_ENABLED | OPENCLAW_DISCORD_ENABLED |
3. Schema Validation Strictness
The new validation layer performs a deep merge and strict schema checking. A configuration missing the new required field botToken (while having legacy token) is flagged as “not configured” rather than falling back gracefully.
Failure Sequence
- Gateway starts and loads config.json
- Configuration loader parses channels.discord object
- Schema validator checks for ‘botToken’ field
- Legacy ’token’ field found but not in new schema
- Validation fails β channel marked as ’not configured’
- Channel remains disabled despite valid legacy config
Architectural Inconsistency
The upgrade path did not include a backward compatibility layer or config migration utility. Users upgrading from older versions experience silent config breakage because:
- No deprecation warning is issued for
tokenfield - No automatic migration is performed
- Error logs do not clearly indicate schema mismatch
π οΈ Step-by-Step Fix
Option 1: Update Configuration File (Recommended)
Step 1: Locate your configuration file
# Default locations checked by OpenClaw:
$ openclaw config --show-path
/etc/openclaw/config.json
~/.config/openclaw/config.json
./openclaw.config.json
Step 2: Backup existing configuration
$ cp /etc/openclaw/config.json /etc/openclaw/config.json.backup-$(date +%Y%m%d)
Step 3: Update the Discord channel configuration
Before (Legacy Schema): json { “channels”: { “discord”: { “enabled”: true, “token”: “YOUR_ACTUAL_BOT_TOKEN_HERE”, “groupPolicy”: “allowlist”, “guilds”: { “xxx”: { “requireMention”: true, “users”: [“xxx”] } } } } }
After (Current Schema): json { “channels”: { “discord”: { “enabled”: true, “botToken”: “YOUR_ACTUAL_BOT_TOKEN_HERE”, “groupPolicy”: “allowlist”, “guilds”: { “xxx”: { “requireMention”: true, “users”: [“xxx”] } } } } }
Step 4: Validate the configuration
$ openclaw config validate --channel discord
Configuration valid for Discord channel
Step 5: Restart the gateway
$ openclaw gateway restart
[INFO] Gateway stopped
[INFO] OpenClaw Gateway v2026.5.7 starting...
[INFO] Configuration loaded successfully
[INFO] Discord channel: enabled
[INFO] Gateway started on port 3000
Option 2: Use Environment Variables
If you prefer environment-based configuration, use the new naming convention:
Step 1: Set the environment variables
$ export OPENCLAW_DISCORD_BOT_TOKEN="YOUR_ACTUAL_BOT_TOKEN_HERE"
$ export OPENCLAW_DISCORD_ENABLED="true"
$ export OPENCLAW_DISCORD_GUILD_ALLOWLIST="xxx"
Step 2: Remove the Discord section from config.json (environment variables take precedence)
Step 3: Verify environment variable loading
$ openclaw channels list --all
Discord: installed, configured, enabled
Option 3: Use OpenClaw Config Migration Utility (if available)
$ openclaw config migrate --from v2026.3.24 --to current
[INFO] Scanning configuration...
[INFO] Found legacy Discord config with 'token' field
[INFO] Migrating to new schema...
[INFO] Renamed 'token' to 'botToken'
[INFO] Configuration migrated successfully
[INFO] Backup saved to: /etc/openclaw/config.json.backup-migrated
π§ͺ Verification
Verification Steps
Step 1: Confirm channel status after fix
$ openclaw channels list --all
Discord: installed, configured, enabled
slack: installed, configured, enabled
telegram: installed, configured, enabled
Expected output: Discord: installed, configured, enabled
Step 2: Verify configuration parsing
$ openclaw config parse --channel discord --show
{
"enabled": true,
"botToken": "******",
"groupPolicy": "allowlist",
"guilds": {
"xxx": {
"requireMention": true,
"users": ["xxx"]
}
}
}
Expected: The botToken field should be present and masked in output.
Step 3: Check gateway logs for Discord initialization
$ openclaw gateway logs --recent 50 | grep -i discord
[INFO] Discord: Initializing gateway connection
[INFO] Discord: Connected to gateway successfully
[INFO] Discord: Syncing guilds...
[INFO] Discord: Ready - connected to 1 guild(s)
Expected: Gateway connection logs should show successful Discord initialization.
Step 4: Test Discord bot functionality
$ openclaw channels test --channel discord
[INFO] Testing Discord channel...
[INFO] Discord: Sending test message...
[INFO] Discord: Test message sent successfully
[INFO] Discord: Test PASSED
Expected: Exit code 0 with success message.
Step 5: Verify with verbose debug output
$ OPENCLAW_DEBUG=true openclaw channels list --all
[DEBUG] Loading configuration from /etc/openclaw/config.json
[DEBUG] Parsing channels.discord configuration
[DEBUG] Discord config schema validation: PASSED
[DEBUG] Discord botToken: loaded (length: 59)
[DEBUG] Discord groupPolicy: allowlist
[DEBUG] Discord enabled: true
Discord: installed, configured, enabled
Expected: Debug output should show schema validation passing.
β οΈ Common Pitfalls
Environment Variable Override Trap
Pitfall: Environment variables from the legacy naming convention are silently ignored.
bash
This will NOT work - using legacy env var
$ export DISCORD_TOKEN=“your-bot-token” $ openclaw channels list –all Discord: installed, not configured, disabled # Still broken!
Fix: Use the new environment variable names: bash $ export OPENCLAW_DISCORD_BOT_TOKEN=“your-bot-token”
Partial Configuration Misinterpretation
Pitfall: Having only some fields in the new schema while others remain in legacy format.
json { “channels”: { “discord”: { “enabled”: true, “token”: “legacy-field-still-present”, “botToken”: "" // Empty new field } } }
The empty botToken takes precedence, causing configuration failure.
Docker Environment Specific Issues
Pitfall: Docker container environment variable passing syntax differences.
bash
Wrong - legacy variable in docker run
$ docker run -e DISCORD_TOKEN=xxx openclaw/gateway
Correct - new variable in docker run
$ docker run -e OPENCLAW_DISCORD_BOT_TOKEN=xxx openclaw/gateway
For docker-compose.yml:
yaml
environment:
- OPENCLAW_DISCORD_BOT_TOKEN=${DISCORD_BOT_TOKEN}
macOS Specific Issues
Pitfall: launchd environment variables not persisting to GUI applications.
If running OpenClaw as a GUI application on macOS, environment variables set in Terminal may not be available. Use the configuration file approach instead.
Case Sensitivity in Configuration Keys
Pitfall: Configuration keys are case-sensitive in the new schema.
json // Wrong - case mismatch { “BotToken”: “xxx” }
// Correct - exact case match { “botToken”: “xxx” }
Permission Issues on Config Files
Pitfall: Config file permissions preventing reading.
bash $ openclaw gateway start [ERROR] Failed to read /etc/openclaw/config.json: Permission denied
Fix: bash $ sudo chown openclaw:openclaw /etc/openclaw/config.json $ sudo chmod 640 /etc/openclaw/config.json
Upgrading Without Backup
Pitfall: Upgrading without first creating a configuration backup, making rollback impossible.
Always backup before upgrading: bash $ cp ~/.config/openclaw/config.json ~/.config/openclaw/config.json.pre-upgrade $ npm install -g openclaw@latest
π Related Errors
Configuration Validation Errors
| Error Code | Description | Resolution |
|---|---|---|
CFG_001 | Missing required field botToken | Add botToken field to Discord config |
CFG_002 | Invalid token format | Verify Discord bot token is valid |
CFG_003 | Schema validation failed | Validate JSON syntax and field names |
CFG_004 | Config file not found | Check config path with openclaw config --show-path |
Channel Initialization Errors
| Error Code | Description | Resolution |
|---|---|---|
CHN_101 | Channel marked as disabled | Check configuration and enable flag |
CHN_102 | Channel not configured | Verify all required fields present |
CHN_103 | Gateway connection failed | Check network and bot token |
CHN_104 | Guild sync failed | Verify bot permissions in Discord |
Historical Related Issues
| Issue | Summary |
|---|---|
#1847 | Discord channel token field documented but not implemented in schema |
#2103 | Environment variable override behavior changed in v2026.4.x |
#2234 | Silent config migration failures causing channel disable |
#2456 | Documentation did not reflect schema changes |
Similar Channel Configuration Regressions
The same schema migration pattern may affect other channels:
bash $ openclaw channels list –all
Check if any of the following show as “not configured”:
Slack: installed, not configured, disabled # May also be affected Telegram: installed, not configured, disabled # May also be affected Matrix: installed, not configured, disabled # May also be affected
For Slack, check for slackToken vs legacy token field similarly.