dify - 💡(How to fix) Fix Saved CHAT prompt history leaks tool_calls onto the message after an assistant tool call

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…

In PromptMessageUtil.prompt_messages_to_prompt_for_saving (api/core/prompt/utils/prompt_message_util.py), CHAT mode initializes tool_calls = [] once, outside the per-message loop, and only reassigns it inside the assistant branch. But the block

if tool_calls:
    prompt["tool_calls"] = tool_calls

runs for every message. So after an assistant message that carries tool_calls, the next message (the tool-result message, and any later user/system message until the next assistant turn) reuses the stale tool_calls list and is wrongly tagged with the previous assistant's tool calls.

Root Cause

In PromptMessageUtil.prompt_messages_to_prompt_for_saving (api/core/prompt/utils/prompt_message_util.py), CHAT mode initializes tool_calls = [] once, outside the per-message loop, and only reassigns it inside the assistant branch. But the block

if tool_calls:
    prompt["tool_calls"] = tool_calls

runs for every message. So after an assistant message that carries tool_calls, the next message (the tool-result message, and any later user/system message until the next assistant turn) reuses the stale tool_calls list and is wrongly tagged with the previous assistant's tool calls.

Fix Action

Fix

Reset tool_calls per loop iteration. A PR with a regression test follows.

Code Example

if tool_calls:
    prompt["tool_calls"] = tool_calls
RAW_BUFFERClick to expand / collapse

Self-checks: searched existing issues, reproduced on latest main.

Summary

In PromptMessageUtil.prompt_messages_to_prompt_for_saving (api/core/prompt/utils/prompt_message_util.py), CHAT mode initializes tool_calls = [] once, outside the per-message loop, and only reassigns it inside the assistant branch. But the block

if tool_calls:
    prompt["tool_calls"] = tool_calls

runs for every message. So after an assistant message that carries tool_calls, the next message (the tool-result message, and any later user/system message until the next assistant turn) reuses the stale tool_calls list and is wrongly tagged with the previous assistant's tool calls.

Impact

Saved/displayed prompt history (CHAT mode) mis-attributes tool_calls to non-assistant messages. Affects the persisted prompt shown for a message — tool_calls appears on roles (tool, user, system) that never produced them.

Expected

tool_calls should appear only on the assistant message that produced them.

Fix

Reset tool_calls per loop iteration. A PR with a regression test follows.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING