April 22, 2026 • Version: Latest (unversioned)

Discord Slash Command Returns 'Done.' Instead of Rich Data

Regression in OpenClaw v Latest where the /status slash command displays 'Done.' text instead of displaying the expected rich embedded data response.

🔍 Symptoms

The /status Discord slash command executes without throwing visible errors but returns only a plain text “Done.” message instead of the expected rich embedded data.

CLI Execution Examples

When the command is invoked, the bot responds with minimal output:

User: /status
Bot: Done.

Expected Response (prior behavior):

User: /status
Bot: [Rich embedded message with status information, model info, system metrics, etc.]

Diagnostic Indicators

  • Exit code: 0 (command completes successfully)
  • No error logs in console output
  • Response arrives promptly (not timing out)
  • Command works in text channel context but fails in DM context
  • Bot has proper APPLICATION_COMMANDS permission scope

Secondary Symptoms

  • Interaction acknowledgment may appear as “Thinking…" before reverting to “Done.”
  • Response lacks embedded formatting, colors, or fields
  • Timestamp on message shows correct execution time
  • Subsequent commands continue to work normally

🧠 Root Cause

The “Done.” response is the default Discord.js fallback message when an interaction response is not properly created or edited after initial acknowledgment.

Technical Failure Sequence

  1. Interaction Received: Discord sends the INTERACTION_CREATE event to the OpenClaw handler
  2. Initial Acknowledgment: OpenClaw calls interaction.reply() with { content: "Done." } as a default fallback
  3. Handler Execution: The actual status handler begins processing data
  4. Response Failure: The handler attempts to use interaction.editReply() or interaction.followUp()
  5. Missing Callback Resolution: The response never reaches the follow-up method due to:
    • Async/await not properly awaited in the handler chain
    • Promise rejection silently swallowed
    • Interaction object reference becoming stale
  6. Default Display: Discord renders the initial "Done." acknowledgment

Architectural Inconsistency

OpenClaw’s Discord adapter changed how interaction deferred responses are handled:

Before (working):

await interaction.reply({ embeds: [statusEmbed] });

After (broken):

await interaction.deferReply();  // Implicit acknowledgment with "Done."
// ... async processing ...
await interaction.editReply({ embeds: [statusEmbed] });  // Fails silently

The deferral pattern assumes the follow-up edit will complete successfully. Any exception in the processing chain causes the “Done.” to persist.

Specific Code Paths Affected

  • src/adapters/discord/interaction-handler.ts: Missing try-catch around response editing
  • src/commands/status/index.ts: Handler may not properly await data fetching
  • src/providers/openclaw/status-service.ts: Data retrieval may throw in certain environments

🛠️ Step-by-Step Fix

Modify the status command handler to respond directly without deferral:

// Before (causes regression)
statusCommand: async (interaction) => {
    await interaction.deferReply();
    const status = await fetchStatusData();
    await interaction.editReply({ embeds: [buildEmbed(status)] });
}

// After (correct)
statusCommand: async (interaction) => {
    const status = await fetchStatusData();
    await interaction.reply({ embeds: [buildEmbed(status)] });
}

Method 2: Add Robust Error Handling

Wrap the deferred response flow with comprehensive error handling:

statusCommand: async (interaction) => {
    await interaction.deferReply({ ephemeral: false }).catch(err => {
        console.error('Defer failed:', err);
        throw err;  // Propagate to prevent silent failure
    });

    try {
        const status = await fetchStatusData();
        const embed = buildEmbed(status);
        await interaction.editReply({ embeds: [embed] }).catch(err => {
            console.error('EditReply failed:', err);
            await interaction.reply({ embeds: [embed] });  // Fallback
        });
    } catch (error) {
        console.error('Status fetch failed:', error);
        await interaction.editReply({
            content: '⚠️ Failed to retrieve status information.',
            embeds: []
        }).catch(() => {
            await interaction.reply('⚠️ Failed to retrieve status information.');
        });
    }
}

Method 3: Verify Adapter Configuration

Ensure the Discord adapter is configured correctly in your OpenClaw setup:

// openclaw.config.ts
export default {
    adapters: {
        discord: {
            intents: ['Guilds', 'GuildMessages', 'DirectMessages'],
            // Explicitly set response mode
            useLegacyContextMenus: false,
            respondOnDefer: false  // Disable implicit "Done." responses
        }
    }
}

Method 4: Check Slash Command Registration

Force re-registration of the slash command to ensure proper permissions:

# Remove existing command
npx openclaw discord commands delete status --guild YOUR_GUILD_ID

# Clear global cache
npx openclaw discord cache clear

# Re-register
npx openclaw discord commands register

# Verify registration
npx openclaw discord commands list

🧪 Verification

Test Commands

1. Verify Command Registration:

npx openclaw discord commands list --verbose
# Expected: /status command appears with correct description and options

2. Test in Public Channel:

# In a text channel (not DM)
/status
# Expected: Rich embed with status data visible to all users

3. Test in DM Context:

# In bot DM
/status
# Expected: Rich embed with status data
# If still shows "Done.": Issue is in DM-specific handling

4. Enable Debug Logging:

# Set environment variable
export LOG_LEVEL=debug
export DEBUG=openclaw:discord:*

# Restart OpenClaw
npx openclaw start

# Execute /status and observe logs
# Look for: "interaction.reply", "interaction.deferReply", "interaction.editReply"

Expected Log Output (Fixed State)

[DEBUG] openclaw:discord:interaction - Received INTERACTION_CREATE for /status
[DEBUG] openclaw:discord:interaction - Calling status handler
[DEBUG] openclaw:discord:interaction - Fetching status data from provider
[DEBUG] openclaw:discord:interaction - Building embed with 5 fields
[INFO] openclaw:discord:interaction - Replying to interaction with embed
[DEBUG] openclaw:discord:interaction - Response sent: 200 OK

Exit Code Verification

# After running verification tests
echo $?
# Expected: 0 (success)

⚠️ Common Pitfalls

Environment-Specific Traps

  • WSL2 Timing Issues: WSL2 clock sync can cause interaction response timeouts. Discord interactions require responses within 3 seconds. Use ntpd or wsl2-hibernate workaround.
  • Docker Container Timeouts: If running in Docker, ensure the container clock matches host. Run docker run --cap-add=SYS_TIME or sync with timedatectl set-ntp true.
  • Windows Defender Firewall: May block WebSocket connections in DM contexts. Add exception for Discord's gateway IPs.

Configuration Missteps

  • Missing Intents: Without Guilds intent, DM interactions may not register properly
  • Ephemeral Default: Some configurations default to ephemeral: true, which can cause "Done." to appear in unexpected locations
  • Stale Cache: Old command definitions cached locally may override registration updates

Handler Anti-Patterns

  • Not Awaiting Async Calls:
    // Wrong
    interaction.deferReply();
    fetchStatusData().then(data => {
        interaction.editReply({ embeds: [data] });  // 'this' context lost
    });
    

    // Correct await interaction.deferReply(); const data = await fetchStatusData(); await interaction.editReply({ embeds: [data] });

  • Swallowed Exceptions: Empty catch blocks prevent debugging
    // Wrong
    try { ... } catch (e) {}
    

    // Correct try { … } catch (e) { console.error(‘Status command failed:’, e); throw e; // or handle gracefully }

  • Race Conditions: Multiple rapid command invocations may conflict with shared state

Model/Provider Edge Cases

  • Opus 4.6 Specific: Some data fields may be null when model context is cold, causing embed building to fail silently
  • Rate Limiting: Discord DM interactions have stricter rate limits; ensure request debouncing

Evidence & Sources

This troubleshooting guide was automatically synthesized by the FixClaw Intelligence Pipeline from community discussions.