dify - ✅(Solved) Fix fix: KeyError crash when updating prompt tools in agent runners [1 pull requests, 2 comments, 2 participants]

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…
GitHub stats
langgenius/dify#35149Fetched 2026-04-15 06:45:51
View on GitHub
Comments
2
Participants
2
Timeline
7
Reactions
1
Author
Participants
Timeline (top)
commented ×2cross-referenced ×1labeled ×1mentioned ×1

Fix Action

Fix

Replace the bare dict lookup with a .get() guard:

for prompt_tool in prompt_messages_tools:
    tool_instance = tool_instances.get(prompt_tool.name)
    if tool_instance:
        self.update_prompt_message_tool(tool_instance, prompt_tool)

Apply the same fix in both fc_agent_runner.py and cot_agent_runner.py.

PR fix notes

PR #35150: fix: guard against KeyError in update_prompt_message_tool loop

Description (problem / solution / changelog)

Closes #35149

Problem

In api/core/agent/fc_agent_runner.py (and cot_agent_runner.py), the loop that updates prompt tools after each iteration calls tool_instances[prompt_tool.name] without checking if the key exists. This raises a KeyError if a prompt tool name has no matching entry in tool_instances, crashing the entire agent run.

Fix

Replace the bare dict index with a .get() guard and skip the update if the tool instance isn't found — the same defensive pattern already used in _handle_invoke_action:

# Before
for prompt_tool in prompt_messages_tools:
    self.update_prompt_message_tool(tool_instances[prompt_tool.name], prompt_tool)

# After
for prompt_tool in prompt_messages_tools:
    tool_instance = tool_instances.get(prompt_tool.name)
    if tool_instance:
        self.update_prompt_message_tool(tool_instance, prompt_tool)

Changed files

  • api/core/agent/fc_agent_runner.py (modified, +3/-1)

Code Example

# fc_agent_runner.py ~line 302
for prompt_tool in prompt_messages_tools:
    self.update_prompt_message_tool(tool_instances[prompt_tool.name], prompt_tool)

---

for prompt_tool in prompt_messages_tools:
    tool_instance = tool_instances.get(prompt_tool.name)
    if tool_instance:
        self.update_prompt_message_tool(tool_instance, prompt_tool)
RAW_BUFFERClick to expand / collapse

Problem

In both api/core/agent/fc_agent_runner.py and api/core/agent/cot_agent_runner.py, the "update prompt tool" loop calls tool_instances[prompt_tool.name] without first checking if prompt_tool.name is a key in tool_instances.

# fc_agent_runner.py ~line 302
for prompt_tool in prompt_messages_tools:
    self.update_prompt_message_tool(tool_instances[prompt_tool.name], prompt_tool)

This raises an unhandled KeyError when a tool present in prompt_messages_tools is not found in tool_instances. While _init_prompt_tools() normally keeps them in sync, tool name collisions or future refactors could break this assumption. The safe pattern—used elsewhere in the codebase (e.g. _handle_invoke_action)—is to guard with a .get() check and skip missing tools.

Steps to Reproduce

  1. Configure an agent app with a mix of API tools and dataset retrieval tools.
  2. Trigger a scenario where the tool name in prompt_messages_tools diverges from the corresponding key in tool_instances (e.g. name mismatch introduced by a plugin update).
  3. Observe an unhandled KeyError crashing the agent run.

Expected

When a prompt tool name is not found in tool_instances, the update should be skipped gracefully instead of raising KeyError.

Fix

Replace the bare dict lookup with a .get() guard:

for prompt_tool in prompt_messages_tools:
    tool_instance = tool_instances.get(prompt_tool.name)
    if tool_instance:
        self.update_prompt_message_tool(tool_instance, prompt_tool)

Apply the same fix in both fc_agent_runner.py and cot_agent_runner.py.

extent analysis

TL;DR

Replace the bare dictionary lookup with a .get() guard to prevent KeyError when a prompt tool name is not found in tool_instances.

Guidance

  • Identify the lines of code in fc_agent_runner.py and cot_agent_runner.py where the tool_instances dictionary is accessed without a .get() check.
  • Apply the suggested fix by replacing the bare lookup with a .get() call, as shown in the provided example.
  • Verify that the fix works by triggering the scenario that previously caused the KeyError and checking that the agent run no longer crashes.
  • Review other parts of the codebase to ensure that this pattern is consistently applied to prevent similar issues.

Example

for prompt_tool in prompt_messages_tools:
    tool_instance = tool_instances.get(prompt_tool.name)
    if tool_instance:
        self.update_prompt_message_tool(tool_instance, prompt_tool)

Notes

This fix assumes that skipping the update when a tool instance is not found is the desired behavior. If a different behavior is required, additional modifications may be necessary.

Recommendation

Apply the workaround by replacing the bare dictionary lookup with a .get() guard, as this will prevent the KeyError and ensure that the agent run does not crash when a prompt tool name is not found in tool_instances.

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