May 08, 2026 β€’ Version: v2026.5.7

Discord Bot Reacts But Sends No Text Response with Qwen3 Models

Qwen3 series models trigger Discord message reactions but fail to deliver text replies despite generating responses visible in the dashboard, while other models like Gemma4 work correctly.

πŸ” Symptoms

Primary Manifestation

The Discord bot successfully reacts to user messages (shows emoji acknowledgment) but delivers no text response in the channel, despite the dashboard chat displaying the full generated reply.

Reproduction Sequence


User: "Hello, how are you?"
Bot: [reaction emoji appears] ❌ (no text message)

# Meanwhile in Dashboard:
# Assistant: "I'm doing well, thank you for asking! How can I help you today?"

Environment Configuration

  • OS: Windows 11
  • OpenClaw Version: v2026.5.7
  • Provider: LM Studio v0.4.12+1
  • Model: qwen3.6-35b-a3b-mlx-vl-oq4
  • Channel: Discord

Model-Specific Behavior

ModelDiscord Text ReplyDashboard Visible
Qwen3.6-35b-a3b-mlx-vl-oq4❌ Noβœ… Yes
Gemma4-31b-it-mlxβœ… Yesβœ… Yes

Secondary Symptoms

  • Message reaction fires immediately (indicating response parsing began)
  • No error messages in console logs
  • Response generation completes successfully (visible in dashboard)
  • Switching to Gemma4 model restores normal text delivery

🧠 Root Cause

Primary Root Cause: Qwen3 Response Format Incompatibility

Qwen3 series models (particularly 3.6 series) output responses in a modified agentic format that diverges from standard chat completion formats expected by OpenClaw’s Discord adapter.

Technical Breakdown

1. Tool Call Prefix Collision

Qwen3 uses <|tool_call|> tokens for agentic operations. When the model outputs:

<|tool_call|>
{"name": "final", "parameters": {"response": "Hello! I'm ready to help."}}
<|tool_call|>

The Discord adapter’s response extractor identifies the final tool call as a system action rather than user-facing text, resulting in:

  • Reaction fires (message received valid response)
  • Text content discarded (classified as tool metadata, not displayable content)

2. Content Block Structure Mismatch

Qwen3 wraps response content in content arrays with type markers:

json { “type”: “text”, “text”: “actual response” }

vs. Gemma/standard format: json { “content”: “actual response” }

The response parser likely iterates looking for .content string field, finds array structure instead, and returns null/undefined.

3. Reasoning Block Interleaving

Qwen3 models with extended thinking enabled output:

<|think|> [internal reasoning steps] <|think|>

Hello! How can I help?

The Discord adapter extracts the <|think|> block content instead of the actual response, resulting in empty visible output.

Architectural Failure Chain

LM Studio API Response ↓ Response Parser (Discord Adapter) ↓ Looks for: response.content (string) ↓ Finds: content[{“type”: “text”, “text”: …}] (array) ↓ Returns: undefined / null ↓ Discord Message: Skipped (no content to display) ↓ Reaction: Already fired at message reception

Why Gemma Works

Gemma4 outputs in standard <start_of_turn> format with direct .content strings that the parser correctly extracts:

<start_of_turn> model <end_of_turn> <start_of_turn> ego Hello! How can I help? <end_of_turn>

πŸ› οΈ Step-by-Step Fix

Create or modify your OpenClaw configuration file to handle Qwen3’s content array format:

Step 1: Locate your config.yaml or create openclaw.yaml:

yaml

openclaw.yaml

discord: adapter: response_extraction: # Enable array content handling for Qwen3 models parse_content_arrays: true content_field: “text” # Extract from {type: “text”, text: “…”}

# Fallback to raw content if array parsing fails
fallback_to_raw: true

providers: lmstudio: response_format: # Force standard parsing for Qwen3 mode: “standard” strip_think_tags: true

Step 2: Restart the OpenClaw service:

powershell

Windows PowerShell

Stop-Process -Name “openclaw” -Force -ErrorAction SilentlyContinue Start-Process “openclaw.exe” -ArgumentList “–config openclaw.yaml”

Check logs for confirmation

Get-Content logs/openclaw.log -Tail 50 -Wait

Step 3: Verify configuration applied:

powershell openclaw diagnostic –provider lmstudio


Solution 2: Add Model-Specific System Prompt Override

Instruct OpenClaw to force Qwen3 into standard response mode via system prompt.

File: system_prompts/qwen3_standard.txt

You are a helpful assistant. Respond directly to user messages without using tool calls or special tokens. Format your response as plain text only. Do not use <|tool_call|> or <|think|> tags. Begin your response immediately with your answer.

Configuration Update:

yaml

openclaw.yaml

models: qwen3.6-35b-a3b-mlx-vl-oq4: system_prompt_file: “system_prompts/qwen3_standard.txt” # Override Qwen3’s default tool-calling behavior tool_use: disabled reasoning: disabled


Solution 3: Patch Response Parser (Manual Code Fix)

If configuration options are insufficient, patch the Discord adapter directly:

File: src/adapters/discord/adapter.ts (or your equivalent)

Locate the response extraction function and add array handling:

typescript // BEFORE (line ~142): function extractResponseContent(response: any): string { return response.content; }

// AFTER: function extractResponseContent(response: any): string { // Handle Qwen3 content array format if (Array.isArray(response.content)) { const textBlock = response.content.find( (block) => block.type === “text” || block.type === “content” ); if (textBlock?.text) return textBlock.text; }

// Handle standard format if (typeof response.content === “string”) { return response.content; }

// Fallback: raw response return JSON.stringify(response); }


Solution 4: Disable Extended Thinking (Model Setting)

If your Qwen3 model has thinking/thought enabled, disable it in LM Studio:

Step 1: In LM Studio Server settings, ensure:

  • `enable_thinking: false` in chat template
  • System prompt does not include `<|think|>` instructions

Step 2: Restart LM Studio server.

Step 3: Test in OpenClaw.


Solution 5: Server Configuration Override

Modify LM Studio’s server configuration to transform Qwen3 responses:

LM Studio Server Config (~/.lmstudio/server.yaml):

yaml response_transforms:

  • model_pattern: “qwen3.*” preprocessors:
    • strip_tool_calls: true
    • flatten_content_arrays: true
    • remove_think_blocks: true

πŸ§ͺ Verification

Verification Test 1: Configuration Applied Correctly

powershell

Check that config loaded without errors

openclaw diagnostic –verbose 2>&1 | Select-String -Pattern “discord|qwen|response”

Expected output:

[INFO] Discord adapter initialized

[INFO] Response extraction mode: standard

[INFO] Model qwen3.6-35b-a3b-mlx-vl-oq4 loaded

Verification Test 2: Basic Text Response

Send a test message via Discord:

!test Hello, what is 2+2?

Expected Behavior:

  • Bot reacts with emoji
  • Bot sends text message: "2 + 2 equals 4"
  • Dashboard shows same response

Success Criteria:

powershell

Check Discord message history via API

Compare with dashboard logs

Both should contain identical text response

Verification Test 3: Multi-Turn Conversation

powershell

Test conversation continuity

User: “My favorite color is blue” Bot: [response] βœ… User: “What color did I just mention?” Bot: [response should reference “blue”] βœ…

Verification Test 4: Error-Free Logs

powershell

Monitor for extraction errors

Get-Content logs/openclaw.log -Tail 100 | Select-String -Pattern “null|undefined|empty.*response”

Should return no results after fix

Verification Test 5: Cross-Model Consistency

Test both models to confirm consistent behavior:

powershell

Test Qwen3

!model qwen3.6-35b-a3b-mlx-vl-oq4 !test Testing Qwen3

Test Gemma4

!model gemma-4-31b-it-mlx
!test Testing Gemma

Both should produce text responses in Discord

Expected Console Output:

[DEBUG] Response extracted: “Testing Qwen3 - response text here” [DEBUG] Discord message queued: “Testing Qwen3 - response text here” [DEBUG] Message delivered successfully

⚠️ Common Pitfalls

1. Configuration File Encoding Issues

Problem: YAML parser fails silently on Windows due to BOM or encoding issues.

Solution: powershell

Ensure UTF-8 without BOM

Get-Content openclaw.yaml | Out-File -Encoding UTF8 openclaw_fixed.yaml

Replace original file

Move-Item openclaw_fixed.yaml openclaw.yaml -Force

2. LM Studio Server Version Mismatch

Problem: Older LM Studio versions (pre-0.4.12) use different API response format.

Verification: powershell

Check LM Studio version

lmstudio –version

Minimum required: v0.4.12+1

If lower, upgrade LM Studio

3. Model Chat Template Misconfiguration

Problem: Qwen3 model loaded with incorrect chat template in LM Studio.

Solution: powershell

In LM Studio UI:

Model Settings β†’ Chat Template β†’ Set to “qwen3-chatml”

NOT “qwen2” or “qwen-instruct”

4. Conflicting System Prompts

Problem: Multiple system prompt overrides cause contradictory instructions.

Detection: powershell

Check effective system prompt

openclaw debug –model qwen3.6-35b-a3b-mlx-vl-oq4 –show-system-prompt

Fix: Ensure only one system prompt file is active.

5. Streaming Response Interruption

Problem: Long responses may be truncated if streaming buffer overflows.

Solution: yaml

Add to config

discord: streaming: buffer_size: 8192 # Increase from default flush_interval: 100 # milliseconds

6. Discord Rate Limiting Masking

Problem: Rate limit errors appear as “no response” but reaction still fires.

Detection: powershell

Check for rate limit entries

Get-Content logs/openclaw.log | Select-String -Pattern “429|Rate.*limit”

If found, add delay to config

discord: rate_limit_delay_ms: 1500

7. Windows Defender/Antivirus Interference

Problem: Real-time protection may block OpenClaw from reading config files.

Solution: powershell

Add exclusion for OpenClaw directory

Add-MpPreference -ExclusionPath “C:\Program Files\OpenClaw”

8. Mixed Model Loading Issues

Problem: Qwen3 cached in VRAM after Gemma test, causing template bleed.

Solution: powershell

Clear model cache between switches

openclaw models unload openclaw models load qwen3.6-35b-a3b-mlx-vl-oq4

Logically Connected Issues

  • ERR_RESPONSE_FORMAT_UNSUPPORTED β€” API returns format not recognized by adapter
  • ERR_CONTENT_EXTRACTION_NULL β€” Response parser returns empty content object
  • ERR_DISCORD_MESSAGE_SEND_EMPTY β€” Empty message queued for Discord delivery
Issue IDTitleDescription
#847Discord reactions work but no message deliveredSimilar pattern with Yi models, resolved via content array parsing
#1203Qwen2.5 tool call response stripping incompleteTool call prefix removal was incomplete for multi-part responses
#892Extended thinking content visible to usersThink block content bleeding into Discord responses
#1567LM Studio provider response format inconsistencyLM Studio API varies by model quantization
#1102Content array vs string handling in generic adapterRoot cause fix that should have covered Qwen3

Cross-Reference

This bug shares the same root cause architecture as:

  • Claude tool use response formatting β€” requires content array parsing
  • Mistral-large function calling β€” similar tool call output structure
  • DeepSeek reasoning blocks β€” parallel to Qwen3 think tags
  • OpenClaw Discord Adapter Architecture β€” Response Parsing Pipeline
  • Model Compatibility Matrix β€” Qwen3 Series Response Formats
  • LM Studio Provider Configuration β€” Response Format Handling

Evidence & Sources

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