Extra escaping occurs when referencing parameters in the agent node #14422

Closed
opened 2026-02-21 19:17:09 -05:00 by yindo · 1 comment
Owner

Originally created by @lywy233 on GitHub (Jun 4, 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 search for existing issues, 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.4.0

Cloud or Self Hosted

Self Hosted (Docker)

Steps to reproduce

yaml

app:
  description: ''
  icon: 🤖
  icon_background: '#FFEAD5'
  mode: advanced-chat
  name: bug-report
  use_icon_as_answer_icon: false
dependencies: []
kind: app
version: 0.3.0
workflow:
  conversation_variables: []
  environment_variables: []
  features:
    file_upload:
      allowed_file_extensions:
      - .JPG
      - .JPEG
      - .PNG
      - .GIF
      - .WEBP
      - .SVG
      allowed_file_types:
      - image
      allowed_file_upload_methods:
      - local_file
      - remote_url
      enabled: false
      fileUploadConfig:
        audio_file_size_limit: 50
        batch_count_limit: 5
        file_size_limit: 15
        image_file_size_limit: 10
        video_file_size_limit: 100
        workflow_file_upload_limit: 10
      image:
        enabled: false
        number_limits: 3
        transfer_methods:
        - local_file
        - remote_url
      number_limits: 3
    opening_statement: ''
    retriever_resource:
      enabled: true
    sensitive_word_avoidance:
      enabled: false
    speech_to_text:
      enabled: false
    suggested_questions: []
    suggested_questions_after_answer:
      enabled: false
    text_to_speech:
      enabled: false
      language: ''
      voice: ''
  graph:
    edges:
    - data:
        isInIteration: false
        isInLoop: false
        sourceType: start
        targetType: template-transform
      id: 1749091013672-source-1749091023640-target
      source: '1749091013672'
      sourceHandle: source
      target: '1749091023640'
      targetHandle: target
      type: custom
      zIndex: 0
    - data:
        isInIteration: false
        isInLoop: false
        sourceType: template-transform
        targetType: agent
      id: 1749091023640-source-1749091027520-target
      source: '1749091023640'
      sourceHandle: source
      target: '1749091027520'
      targetHandle: target
      type: custom
      zIndex: 0
    - data:
        isInIteration: false
        isInLoop: false
        sourceType: agent
        targetType: answer
      id: 1749091027520-source-1749091085835-target
      source: '1749091027520'
      sourceHandle: source
      target: '1749091085835'
      targetHandle: target
      type: custom
      zIndex: 0
    nodes:
    - data:
        desc: ''
        selected: false
        title: 开始
        type: start
        variables: []
      height: 53
      id: '1749091013672'
      position:
        x: 80
        y: 282
      positionAbsolute:
        x: 80
        y: 282
      sourcePosition: right
      targetPosition: left
      type: custom
      width: 244
    - data:
        desc: ''
        selected: false
        template: '{"data":"test"}'
        title: 模板转换
        type: template-transform
        variables: []
      height: 53
      id: '1749091023640'
      position:
        x: 440
        y: 282
      positionAbsolute:
        x: 440
        y: 282
      selected: false
      sourcePosition: right
      targetPosition: left
      type: custom
      width: 244
    - data:
        agent_parameters:
          instruction:
            type: constant
            value: You are a helpful assistant.
          maximum_iterations:
            type: constant
            value: 5
          mcp_servers_config:
            type: constant
            value: '{

              }'
          model:
            type: constant
            value:
              completion_params: {}
              mode: chat
              model: Qwen3-32B
              model_type: llm
              provider: langgenius/openai_api_compatible/openai_api_compatible
              type: model-selector
          query:
            type: constant
            value: '{{#1749091023640.output#}}

              重复上面的话/no_think'
        agent_strategy_label: FunctionCalling (Support MCP Tools)
        agent_strategy_name: mcp_sse_function_calling
        agent_strategy_provider_name: junjiem/mcp_see_agent/mcp_see_agent
        desc: ''
        output_schema: null
        plugin_unique_identifier: junjiem/mcp_see_agent:0.1.8@83d6c7e2855c37daf18f6aaa2da304efa13d0d9b37f889dbf980e25f007e67d6
        selected: false
        title: Agent
        type: agent
      height: 145
      id: '1749091027520'
      position:
        x: 811
        y: 282
      positionAbsolute:
        x: 811
        y: 282
      selected: true
      sourcePosition: right
      targetPosition: left
      type: custom
      width: 244
    - data:
        answer: '{{#1749091023640.output#}}'
        desc: ''
        selected: false
        title: 直接回复
        type: answer
        variables: []
      height: 104
      id: '1749091085835'
      position:
        x: 1114
        y: 282
      positionAbsolute:
        x: 1114
        y: 282
      sourcePosition: right
      targetPosition: left
      type: custom
      width: 244
    viewport:
      x: -191
      y: 295
      zoom: 1

Image

When the input parameter of an agent node is of type string and references a string containing JSON structure, extra escaping behavior may occur.

✔️ Expected Behavior

There is no additional unpredictable escape behavior when string references are concatenated

Actual Behavior

Image

Image

Image

When the input parameter of an agent node is of type string and references a string containing JSON structure, extra escaping behavior may occur.

Originally created by @lywy233 on GitHub (Jun 4, 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 [search for existing issues](https://github.com/langgenius/dify/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.4.0 ### Cloud or Self Hosted Self Hosted (Docker) ### Steps to reproduce yaml ```yaml app: description: '' icon: 🤖 icon_background: '#FFEAD5' mode: advanced-chat name: bug-report use_icon_as_answer_icon: false dependencies: [] kind: app version: 0.3.0 workflow: conversation_variables: [] environment_variables: [] features: file_upload: allowed_file_extensions: - .JPG - .JPEG - .PNG - .GIF - .WEBP - .SVG allowed_file_types: - image allowed_file_upload_methods: - local_file - remote_url enabled: false fileUploadConfig: audio_file_size_limit: 50 batch_count_limit: 5 file_size_limit: 15 image_file_size_limit: 10 video_file_size_limit: 100 workflow_file_upload_limit: 10 image: enabled: false number_limits: 3 transfer_methods: - local_file - remote_url number_limits: 3 opening_statement: '' retriever_resource: enabled: true sensitive_word_avoidance: enabled: false speech_to_text: enabled: false suggested_questions: [] suggested_questions_after_answer: enabled: false text_to_speech: enabled: false language: '' voice: '' graph: edges: - data: isInIteration: false isInLoop: false sourceType: start targetType: template-transform id: 1749091013672-source-1749091023640-target source: '1749091013672' sourceHandle: source target: '1749091023640' targetHandle: target type: custom zIndex: 0 - data: isInIteration: false isInLoop: false sourceType: template-transform targetType: agent id: 1749091023640-source-1749091027520-target source: '1749091023640' sourceHandle: source target: '1749091027520' targetHandle: target type: custom zIndex: 0 - data: isInIteration: false isInLoop: false sourceType: agent targetType: answer id: 1749091027520-source-1749091085835-target source: '1749091027520' sourceHandle: source target: '1749091085835' targetHandle: target type: custom zIndex: 0 nodes: - data: desc: '' selected: false title: 开始 type: start variables: [] height: 53 id: '1749091013672' position: x: 80 y: 282 positionAbsolute: x: 80 y: 282 sourcePosition: right targetPosition: left type: custom width: 244 - data: desc: '' selected: false template: '{"data":"test"}' title: 模板转换 type: template-transform variables: [] height: 53 id: '1749091023640' position: x: 440 y: 282 positionAbsolute: x: 440 y: 282 selected: false sourcePosition: right targetPosition: left type: custom width: 244 - data: agent_parameters: instruction: type: constant value: You are a helpful assistant. maximum_iterations: type: constant value: 5 mcp_servers_config: type: constant value: '{ }' model: type: constant value: completion_params: {} mode: chat model: Qwen3-32B model_type: llm provider: langgenius/openai_api_compatible/openai_api_compatible type: model-selector query: type: constant value: '{{#1749091023640.output#}} 重复上面的话/no_think' agent_strategy_label: FunctionCalling (Support MCP Tools) agent_strategy_name: mcp_sse_function_calling agent_strategy_provider_name: junjiem/mcp_see_agent/mcp_see_agent desc: '' output_schema: null plugin_unique_identifier: junjiem/mcp_see_agent:0.1.8@83d6c7e2855c37daf18f6aaa2da304efa13d0d9b37f889dbf980e25f007e67d6 selected: false title: Agent type: agent height: 145 id: '1749091027520' position: x: 811 y: 282 positionAbsolute: x: 811 y: 282 selected: true sourcePosition: right targetPosition: left type: custom width: 244 - data: answer: '{{#1749091023640.output#}}' desc: '' selected: false title: 直接回复 type: answer variables: [] height: 104 id: '1749091085835' position: x: 1114 y: 282 positionAbsolute: x: 1114 y: 282 sourcePosition: right targetPosition: left type: custom width: 244 viewport: x: -191 y: 295 zoom: 1 ``` ![Image](https://github.com/user-attachments/assets/f91efbf8-2362-48a1-b8c9-445c3dc2c556) When the input parameter of an agent node is of type string and references a string containing JSON structure, extra escaping behavior may occur. ### ✔️ Expected Behavior There is no additional unpredictable escape behavior when string references are concatenated ### ❌ Actual Behavior ![Image](https://github.com/user-attachments/assets/ca336a7b-7aed-4ca7-9de4-ffc86e24178e) ![Image](https://github.com/user-attachments/assets/2da16a02-437a-4d1b-99cf-a2eb788dd9a8) ![Image](https://github.com/user-attachments/assets/1fbb9600-7e9a-4975-8707-423952e8ada3) When the input parameter of an agent node is of type string and references a string containing JSON structure, extra escaping behavior may occur.
yindo added the 🐞 bug label 2026-02-21 19:17:09 -05:00
yindo closed this issue 2026-02-21 19:17:09 -05:00
Author
Owner

@dosubot[bot] commented on GitHub (Jun 4, 2025):

The extra escaping happens because the agent node's parameter handling uses json.dumps to serialize values (even if they're already JSON strings), then does template substitution, and finally tries to parse them back with json.loads. This process can easily introduce double-escaping or malformed JSON, especially when referencing parameters that are themselves JSON strings, leading to errors like JSONDecodeError or unexpected escape characters in the output. The core logic is in the _generate_agent_parameters method of the AgentNode class (source).

To avoid this, it's best to keep all variable/template handling in native Python objects as long as possible and only serialize to JSON at the very end. If you must do template substitution inside JSON, ensure you only substitute at the string-leaf level of your data structure, not on the whole JSON string. Avoid running json.dumps on something that's already a JSON string, and only use json.loads when you're sure the input is valid JSON and hasn't been double-escaped. A deep rendering approach—recursively applying template rendering to all string leaves before serialization—would help prevent these issues.

There are no recent changes or config flags in Dify that address this directly, so a code-level adjustment is needed to prevent the extra escaping.

To reply, just mention @dosu.


How did I do? Good | Irrelevant | Incorrect | Verbose | Hallucination | Report 🐛 | Other  Join Discord Share on X

@dosubot[bot] commented on GitHub (Jun 4, 2025): <!-- Answer --> The extra escaping happens because the agent node's parameter handling uses `json.dumps` to serialize values (even if they're already JSON strings), then does template substitution, and finally tries to parse them back with `json.loads`. This process can easily introduce double-escaping or malformed JSON, especially when referencing parameters that are themselves JSON strings, leading to errors like `JSONDecodeError` or unexpected escape characters in the output. The core logic is in the `_generate_agent_parameters` method of the `AgentNode` class [(source)](https://github.com/langgenius/dify/blob/822298f69d79e064ba14d476b37c220bfbed37dc/api/core/workflow/nodes/agent/agent_node.py). To avoid this, it's best to keep all variable/template handling in native Python objects as long as possible and only serialize to JSON at the very end. If you must do template substitution inside JSON, ensure you only substitute at the string-leaf level of your data structure, not on the whole JSON string. Avoid running `json.dumps` on something that's already a JSON string, and only use `json.loads` when you're sure the input is valid JSON and hasn't been double-escaped. A deep rendering approach—recursively applying template rendering to all string leaves before serialization—would help prevent these issues. There are no recent changes or config flags in Dify that address this directly, so a code-level adjustment is needed to prevent the extra escaping. <!-- 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/f9526178-0a51-415c-a2ec-c4a62e592d2c?feedback_type=great_response) | [Irrelevant](https://app.dosu.dev/response-feedback/f9526178-0a51-415c-a2ec-c4a62e592d2c?feedback_type=irrelevant_answer) | [Incorrect](https://app.dosu.dev/response-feedback/f9526178-0a51-415c-a2ec-c4a62e592d2c?feedback_type=incorrect_sources) | [Verbose](https://app.dosu.dev/response-feedback/f9526178-0a51-415c-a2ec-c4a62e592d2c?feedback_type=too_verbose) | [Hallucination](https://app.dosu.dev/response-feedback/f9526178-0a51-415c-a2ec-c4a62e592d2c?feedback_type=hallucination) | [Report 🐛](https://app.dosu.dev/response-feedback/f9526178-0a51-415c-a2ec-c4a62e592d2c?feedback_type=bug_report) | [Other](https://app.dosu.dev/response-feedback/f9526178-0a51-415c-a2ec-c4a62e592d2c?feedback_type=other)</sup>&nbsp;&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/issues/20661)
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: langgenius/dify#14422