Error in agent node using Pro/deepseek-ai/DeepSeek-V3.2(siliconflow) with think mode #891

Closed
opened 2026-02-16 10:20:52 -05:00 by yindo · 3 comments
Owner

Originally created by @leslie2046 on GitHub (Dec 20, 2025).

Self Checks

  • This is only for bug report, if you would like to ask a question, please head to Discussions.
  • I have searched for existing issues Dify issues & Dify Official Plugins, including closed ones.
  • I confirm that I am using English to submit this report (我已阅读并同意 Language Policy).
  • [FOR CHINESE USERS] 请务必使用英文提交 Issue,否则会被关闭。谢谢!:)
  • Please do not modify this template :) and fill in all the required fields.

Dify version

1.11.1

Plugin version

0.0.38

Cloud or Self Hosted

Self Hosted (Docker)

Steps to reproduce

Image

✔️ Error log

Run failed: Failed to transform agent message: req_id: 83c93e6a67 PluginInvokeError: {"args":{},"error_type":"Exception","message":"read llm model failed: request failed: req_id: 600135f82c PluginInvokeError: {"args":{"description":"[models] Error: API request failed with status code 400: {\"code\":20015,\"message\":\"\\\"messages\\\" in request are illegal.\",\"data\":null}"},"error_type":"InvokeError","message":"[models] Error: API request failed with status code 400: {\"code\":20015,\"message\":\"\\\"messages\\\" in request are illegal.\",\"data\":null}"}"}

Originally created by @leslie2046 on GitHub (Dec 20, 2025). ### Self Checks - [x] This is only for bug report, if you would like to ask a question, please head to [Discussions](https://github.com/langgenius/dify/discussions/categories/general). - [x] I have searched for existing issues [Dify issues](https://github.com/langgenius/dify/issues) & [Dify Official Plugins](https://github.com/langgenius/dify-official-plugins/issues), including closed ones. - [x] I confirm that I am using English to submit this report (我已阅读并同意 [Language Policy](https://github.com/langgenius/dify/issues/1542)). - [x] [FOR CHINESE USERS] 请务必使用英文提交 Issue,否则会被关闭。谢谢!:) - [x] Please do not modify this template :) and fill in all the required fields. ### Dify version 1.11.1 ### Plugin version 0.0.38 ### Cloud or Self Hosted Self Hosted (Docker) ### Steps to reproduce <img width="1200" height="695" alt="Image" src="https://github.com/user-attachments/assets/5d128eae-114b-4d08-933e-8cfd174d77a7" /> ### ✔️ Error log Run failed: Failed to transform agent message: req_id: 83c93e6a67 PluginInvokeError: {"args":{},"error_type":"Exception","message":"read llm model failed: request failed: req_id: 600135f82c PluginInvokeError: {\"args\":{\"description\":\"[models] Error: API request failed with status code 400: {\\\"code\\\":20015,\\\"message\\\":\\\"\\\\\\\"messages\\\\\\\" in request are illegal.\\\",\\\"data\\\":null}\"},\"error_type\":\"InvokeError\",\"message\":\"[models] Error: API request failed with status code 400: {\\\"code\\\":20015,\\\"message\\\":\\\"\\\\\\\"messages\\\\\\\" in request are illegal.\\\",\\\"data\\\":null}\"}"}
yindo added the bug label 2026-02-16 10:20:52 -05:00
yindo closed this issue 2026-02-16 10:20:52 -05:00
Author
Owner

@dosubot[bot] commented on GitHub (Dec 20, 2025):

This error is likely caused by malformed or improperly escaped content in the messages payload sent to DeepSeek v3.2, especially when using think mode or function calling. The message array is built in several stages: agent parameters are rendered (sometimes as JSON strings), then converted and serialized before being sent to DeepSeek. If any step introduces double-escaped JSON, stray backslashes, or non-JSON-compliant content (for example, by injecting literal JSON strings into message fields that are then serialized again), DeepSeek will reject the request with a 400 and code 20015"messages in request are illegal".

In the current code, tool call arguments and some prompt content are serialized with json.dumps(..., ensure_ascii=False), but if a stringified JSON object is injected into a message and then the whole message array is serialized again, you can end up with illegal escape sequences or double-encoded JSON. This is especially likely if you use templates or variables that already contain JSON strings, or if you manually construct message content with embedded JSON.

To troubleshoot:

  • Check any custom templates, variables, or tool call arguments for embedded JSON strings or escape characters.
  • Avoid injecting raw JSON strings into message fields; always pass structured objects and let the serialization layer handle encoding.
  • If possible, log or inspect the final payload just before it is sent to DeepSeek to spot double-escaped strings or illegal characters.
  • If you use think mode, ensure that any <think>...</think> tags or reasoning content are properly stripped or sanitized before serialization, as the OpenAI-compatible wrapper does some mutation here"OpenAI-compatible LLM wrapper".

Recent updates to DeepSeek v3.2 support do not mention changes to message formatting or escaping, so this is likely a data/formatting issue in your workflow or agent configuration, not a plugin bug"DeepSeek v3.2 PR".

If you can, try to capture and share the actual messages payload being sent to DeepSeek for further debugging.

To reply, just mention @dosu.


How did I do? Good | Irrelevant | Incorrect | Verbose | Hallucination | Report 🐛 | Other

Open in Cursor Join Discord Share on X

@dosubot[bot] commented on GitHub (Dec 20, 2025): <!-- Answer --> This error is likely caused by malformed or improperly escaped content in the messages payload sent to DeepSeek v3.2, especially when using think mode or function calling. The message array is built in several stages: agent parameters are rendered (sometimes as JSON strings), then converted and serialized before being sent to DeepSeek. If any step introduces double-escaped JSON, stray backslashes, or non-JSON-compliant content (for example, by injecting literal JSON strings into message fields that are then serialized again), DeepSeek will reject the request with a 400 and code 20015["messages in request are illegal"](https://github.com/langgenius/dify/blob/7501360663efe879d716d8a962ce80181a21596b/api/core/plugin/impl/model.py#L145-L192). In the current code, tool call arguments and some prompt content are serialized with `json.dumps(..., ensure_ascii=False)`, but if a stringified JSON object is injected into a message and then the whole message array is serialized again, you can end up with illegal escape sequences or double-encoded JSON. This is especially likely if you use templates or variables that already contain JSON strings, or if you manually construct message content with embedded JSON. To troubleshoot: - Check any custom templates, variables, or tool call arguments for embedded JSON strings or escape characters. - Avoid injecting raw JSON strings into message fields; always pass structured objects and let the serialization layer handle encoding. - If possible, log or inspect the final payload just before it is sent to DeepSeek to spot double-escaped strings or illegal characters. - If you use think mode, ensure that any `<think>...</think>` tags or reasoning content are properly stripped or sanitized before serialization, as the OpenAI-compatible wrapper does some mutation here["OpenAI-compatible LLM wrapper"](https://github.com/langgenius/dify-official-plugins/blob/559b4b66fa55c40aa95dc5717f586c8ef7aa7237/models/openai_api_compatible/models/llm/llm.py#L25-L201). Recent updates to DeepSeek v3.2 support do not mention changes to message formatting or escaping, so this is likely a data/formatting issue in your workflow or agent configuration, not a plugin bug["DeepSeek v3.2 PR"](https://github.com/langgenius/dify-official-plugins/pull/2179). If you can, try to capture and share the actual messages payload being sent to DeepSeek for further debugging. <!-- Dosu Comment Footer --> *To reply, just mention [@dosu](https://go.dosu.dev/dosubot).* --- <sup>How did I do? [Good](https://app.dosu.dev/response-feedback/4c773ec5-ed77-491f-a238-b30b410936ab?feedback_type=great_response) | [Irrelevant](https://app.dosu.dev/response-feedback/4c773ec5-ed77-491f-a238-b30b410936ab?feedback_type=irrelevant_answer) | [Incorrect](https://app.dosu.dev/response-feedback/4c773ec5-ed77-491f-a238-b30b410936ab?feedback_type=incorrect_sources) | [Verbose](https://app.dosu.dev/response-feedback/4c773ec5-ed77-491f-a238-b30b410936ab?feedback_type=too_verbose) | [Hallucination](https://app.dosu.dev/response-feedback/4c773ec5-ed77-491f-a238-b30b410936ab?feedback_type=hallucination) | [Report 🐛](https://app.dosu.dev/response-feedback/4c773ec5-ed77-491f-a238-b30b410936ab?feedback_type=bug_report) | [Other](https://app.dosu.dev/response-feedback/4c773ec5-ed77-491f-a238-b30b410936ab?feedback_type=other)</sup> [![Open in Cursor](https://dosu.dev/dosu-in-cursor.svg)](https://cursor.com/link/prompt?text=This%20error%20is%20likely%20caused%20by%20malformed%20or%20improperly%20escaped%20content%20in%20the%20messages%20payload%20sent%20to%20DeepSeek%20v3.2%2C%20especially%20when%20using%20think%20mode%20or%20function%20calling.%20The%20message%20array%20is%20built%20in%20several%20stages%3A%20agent%20parameters%20are%20rendered%20%28sometimes%20as%20JSON%20strings%29%2C%20then%20converted%20and%20serialized%20before%20being%20sent%20to%20DeepSeek.%20If%20any%20step%20introduces%20double-escaped%20JSON%2C%20stray%20backslashes%2C%20or%20non-JSON-compliant%20content%20%28for%20example%2C%20by%20injecting%20literal%20JSON%20strings%20into%20message%20fields%20that%20are%20then%20serialized%20again%29%2C%20DeepSeek%20will%20reject%20the%20request%20with%20a%20400%20and%20code%2020015%5B%22messages%20in%20request%20are%20illegal%22%5D%28https%3A//github.com/langgenius/dify/blob/7501360663efe879d716d8a962ce80181a21596b/api/core/plugin/impl/model.py%23L145-L192%29.%0A%0AIn%20the%20current%20code%2C%20tool%20call%20arguments%20and%20some%20prompt%20content%20are%20serialized%20with%20%60json.dumps%28...%2C%20ensure_ascii%3DFalse%29%60%2C%20but%20if%20a%20stringified%20JSON%20object%20is%20injected%20into%20a%20message%20and%20then%20the%20whole%20message%20array%20is%20serialized%20again%2C%20you%20can%20end%20up%20with%20illegal%20escape%20sequences%20or%20double-encoded%20JSON.%20This%20is%20especially%20likely%20if%20you%20use%20templates%20or%20variables%20that%20already%20contain%20JSON%20strings%2C%20or%20if%20you%20manually%20construct%20message%20content%20with%20embedded%20JSON.%0A%0ATo%20troubleshoot%3A%0A-%20Check%20any%20custom%20templates%2C%20variables%2C%20or%20tool%20call%20arguments%20for%20embedded%20JSON%20strings%20or%20escape%20characters.%0A-%20Avoid%20injecting%20raw%20JSON%20strings%20into%20message%20fields%3B%20always%20pass%20structured%20objects%20and%20let%20the%20serialization%20layer%20handle%20encoding.%0A-%20If%20possible%2C%20log%20or%20inspect%20the%20final%20payload%20just%20before%20it%20is%20sent%20to%20DeepSeek%20to%20spot%20double-escaped%20strings%20or%20illegal%20characters.%0A-%20If%20you%20use%20think%20mode%2C%20ensure%20that%20any%20%60%3Cthink%3E...%3C/think%3E%60%20tags%20or%20reasoning%20content%20are%20properly%20stripped%20or%20sanitized%20before%20serialization%2C%20as%20the%20OpenAI-compatible%20wrapper%20does%20some%20mutation%20here%5B%22OpenAI-compatible%20LLM%20wrapper%22%5D%28https%3A//github.com/langgenius/dify-official-plugins/blob/559b4b66fa55c40aa95dc5717f586c8ef7aa7237/models/openai_api_compatible/models/llm/llm.py%23L25-L201%29.%0A%0ARecent%20updates%20to%20DeepSeek%20v3.2%20support%20do%20not%20mention%20changes%20to%20message%20formatting%20or%20escaping%2C%20so%20this%20is%20likely%20a%20data/formatting%20issue%20in%20your%20workflow%20or%20agent%20configuration%2C%20not%20a%20plugin%20bug%5B%22DeepSeek%20v3.2%20PR%22%5D%28https%3A//github.com/langgenius/dify-official-plugins/pull/2179%29.%0A%0AIf%20you%20can%2C%20try%20to%20capture%20and%20share%20the%20actual%20messages%20payload%20being%20sent%20to%20DeepSeek%20for%20further%20debugging.)&nbsp;[![Join Discord](https://img.shields.io/badge/join-5865F2?logo=discord&logoColor=white&label=)](https://go.dosu.dev/discord-bot)&nbsp;[![Share on X](https://img.shields.io/badge/X-share-black)](https://twitter.com/intent/tweet?text=%40dosu_ai%20helped%20me%20solve%20this%20issue!&url=https%3A//github.com/langgenius/dify-official-plugins/issues/2304)
Author
Owner

@leslie2046 commented on GitHub (Dec 20, 2025):

import os
import sys
import json
from openai import OpenAI

def definitive_test_variant():
    api_key = 'sk-xxxxxxxxxxxxxxxxxxxxxxxxxx'
    client = OpenAI(api_key=api_key, base_url="https://api.siliconflow.cn/v1")
    model_name = "Pro/deepseek-ai/DeepSeek-V3.2"

    def check_scenario(name, messages, tools=None):
        print(f"\n[Testing Scenario] {name}...")
        try:
            client.chat.completions.create(
                model=model_name,
                messages=messages,
                tools=tools,
                max_tokens=10,
                extra_body={"enable_thinking": True}
            )
            print(f"✅ PASSED")
        except Exception as e:
            print(f"❌ FAILED: {e}")
            if "20015" in str(e):
                print(">>> FOUND IT! This is what SiliconFlow considers 'illegal'.")

    # 场景 : 连续两条 Assistant 消息,两条都有非空 content
    # 这是验证:如果两条都有内容,是否还会报错?如果这个报错,那就证明绝对是“连续角色”的问题,与 content 无关。
    check_scenario("Consecutive Assistant", [
        {"role": "user", "content": "Hello"},
        {"role": "assistant", "content": "First thought."},
        {"role": "assistant", "content": "Second thought."}
    ])

if __name__ == "__main__":
    definitive_test_variant()

output:

[Testing Scenario] Consecutive Assistant...
❌ FAILED: Error code: 400 - {'code': 20015, 'message': '"messages" in request are illegal.', 'data': None}>>> FOUND IT! This is what SiliconFlow considers 'illegal'.

Conclusion: Two consecutive assistant messages will trigger an error

@leslie2046 commented on GitHub (Dec 20, 2025): ``` import os import sys import json from openai import OpenAI def definitive_test_variant(): api_key = 'sk-xxxxxxxxxxxxxxxxxxxxxxxxxx' client = OpenAI(api_key=api_key, base_url="https://api.siliconflow.cn/v1") model_name = "Pro/deepseek-ai/DeepSeek-V3.2" def check_scenario(name, messages, tools=None): print(f"\n[Testing Scenario] {name}...") try: client.chat.completions.create( model=model_name, messages=messages, tools=tools, max_tokens=10, extra_body={"enable_thinking": True} ) print(f"✅ PASSED") except Exception as e: print(f"❌ FAILED: {e}") if "20015" in str(e): print(">>> FOUND IT! This is what SiliconFlow considers 'illegal'.") # 场景 : 连续两条 Assistant 消息,两条都有非空 content # 这是验证:如果两条都有内容,是否还会报错?如果这个报错,那就证明绝对是“连续角色”的问题,与 content 无关。 check_scenario("Consecutive Assistant", [ {"role": "user", "content": "Hello"}, {"role": "assistant", "content": "First thought."}, {"role": "assistant", "content": "Second thought."} ]) if __name__ == "__main__": definitive_test_variant() ``` --- output: ``` [Testing Scenario] Consecutive Assistant... ❌ FAILED: Error code: 400 - {'code': 20015, 'message': '"messages" in request are illegal.', 'data': None}>>> FOUND IT! This is what SiliconFlow considers 'illegal'. ``` Conclusion: Two consecutive assistant messages will trigger an error
Author
Owner

@leslie2046 commented on GitHub (Dec 20, 2025):

agent node mode

LOG in siliconflow plugin

  • the first assistant message is LLM's reasoning_content.
  • the second assistant message is LLM's tool call.
    Both normal.
    My previous message also accurately reproduced the logic of the error, so this is actually a problem with the siliconflow server. We may need to do some compatibility processing in the plugin.
2025/12/21 12:23:33 logger.go:61: [INFO]plugin langgenius/siliconflow:0.0.39@99ee57e3a9b1989d7d18563a40c0529119f37a4848e76752ead25663ef9e78d7: instance 019b3f23 log: SiliconFlow invoke input prompt_messages: [
  {
    "role": "system",
    "content": "你是一名助手"
  },
  {
    "role": "user",
    "content": "当前时间"
  },
  {
    "role": "assistant",
    "content": "<think>\n用户询问当前时间。我需要调用current_time工具来获取。让我执行这个操作。\n</think>\n\n"
  },
  {
    "role": "assistant",
    "content": "",
    "tool_calls": [
      {
        "id": "019b3f25f67526e5a5082d1f83a88912",
        "type": "function",
        "function": {
          "name": "current_time",
          "arguments": "{}"
        }
      }
    ]
  },
  {
    "role": "tool",
    "content": "2025-12-21 12:23:31",
    "tool_call_id": "019b3f25f67526e5a5082d1f83a88912"
  }
]

Agent APP mode

https://github.com/langgenius/dify/blob/7501360663efe879d716d8a962ce80181a21596b/api/core/agent/fc_agent_runner.py#L190C12-L205C61
These lines code will avoid consecutive assistant messages,but i think it lost reasoning_content as not expect ,will cause other problems.
LOG in siliconflow plugin

[{
		"role": "system",
		"content": "你是一名助手!\n"
	},
	{
		"role": "user",
		"content": "当前时间"
	},
	{
		"role": "assistant",
		"content": "",
		"tool_calls": [{
			"id": "019b402ef8aa04ddf892cde9ddf37233",
			"type": "function",
			"function": {
				"name": "current_time",
				"arguments": "{}"
			}
		}]
	},
	{
		"role": "tool",
		"content": "2025-12-21 17:12:59",
		"tool_call_id": "019b402ef8aa04ddf892cde9ddf37233"
	}
]
@leslie2046 commented on GitHub (Dec 20, 2025): # agent node mode LOG in siliconflow plugin - the first assistant message is LLM's reasoning_content. - the second assistant message is LLM's tool call. Both normal. My previous message also accurately reproduced the logic of the error, so this is actually a problem with the siliconflow server. We may need to do some compatibility processing in the plugin. ``` 2025/12/21 12:23:33 logger.go:61: [INFO]plugin langgenius/siliconflow:0.0.39@99ee57e3a9b1989d7d18563a40c0529119f37a4848e76752ead25663ef9e78d7: instance 019b3f23 log: SiliconFlow invoke input prompt_messages: [ { "role": "system", "content": "你是一名助手" }, { "role": "user", "content": "当前时间" }, { "role": "assistant", "content": "<think>\n用户询问当前时间。我需要调用current_time工具来获取。让我执行这个操作。\n</think>\n\n" }, { "role": "assistant", "content": "", "tool_calls": [ { "id": "019b3f25f67526e5a5082d1f83a88912", "type": "function", "function": { "name": "current_time", "arguments": "{}" } } ] }, { "role": "tool", "content": "2025-12-21 12:23:31", "tool_call_id": "019b3f25f67526e5a5082d1f83a88912" } ] ``` # Agent APP mode https://github.com/langgenius/dify/blob/7501360663efe879d716d8a962ce80181a21596b/api/core/agent/fc_agent_runner.py#L190C12-L205C61 These lines code will avoid consecutive assistant messages,but i think it lost reasoning_content as not expect ,will cause other problems. LOG in siliconflow plugin ``` [{ "role": "system", "content": "你是一名助手!\n" }, { "role": "user", "content": "当前时间" }, { "role": "assistant", "content": "", "tool_calls": [{ "id": "019b402ef8aa04ddf892cde9ddf37233", "type": "function", "function": { "name": "current_time", "arguments": "{}" } }] }, { "role": "tool", "content": "2025-12-21 17:12:59", "tool_call_id": "019b402ef8aa04ddf892cde9ddf37233" } ] ```
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: langgenius/dify-official-plugins#891