Bug: Redis cache helpers crash on invalid UTF-8 bytes

在 Dify 自托管(Self Hosted Source)环境中运行,使用 Redis 作为后端缓存时触发。该问题影响以下三个核心缓存辅助模块:

Bug: Redis cache helpers crash on invalid UTF-8 bytes

Bug: Redis cache helpers crash on invalid UTF-8 bytes

快速结论:当 Redis 缓存中存储了非 UTF-8 编码的字节数据(例如 b"\xff")时,Dify 的三个缓存助手在 .decode("utf-8") 步骤会抛出 UnicodeDecodeError,导致程序崩溃。优先排查 provider_cache.pytool_parameter_cache.pymodel_provider_cache.pyget() 方法的异常处理是否只捕获了 JSONDecodeError 而遗漏了 UnicodeDecodeError

问题场景

在 Dify 自托管(Self Hosted Source)环境中运行,使用 Redis 作为后端缓存时触发。该问题影响以下三个核心缓存辅助模块:

  • api/core/helper/provider_cache.py
  • api/core/helper/tool_parameter_cache.py
  • api/core/helper/model_provider_cache.py

当 Redis 中存储了损坏或非 UTF-8 字节的数据(例如由于数据写入异常、手动修改、或版本升级导致缓存污染),这些缓存的 get() 方法会在调用 .decode("utf-8") 后立即抛出 UnicodeDecodeError,而不是优雅地返回 None

报错原文

UnicodeDecodeError: 'utf-8' codec can't decode byte 0xff in position 0: invalid start byte

# 触发路径示例(单元级复现):
redis_client.get.return_value = b"\xff"
cache.get()

原因分析

所有三个受影响的缓存助手在 get() 方法的异常处理中,只捕获了 JSONDecodeError,用于处理无法解析的 JSON 数据,但没有捕获 UnicodeDecodeError

当 Redis 返回非 UTF-8 二进制数据时(例如 b"\xff"),.decode("utf-8") 会先于 json.loads() 执行。由于 UnicodeDecodeError 未被捕获,异常会直接传播到调用方,导致程序崩溃。正确的行为应该是像处理坏 JSON 一样返回 None,让调用方回退到真实数据源。

环境排查

  • Dify 版本:main 分支(截止 Issue 关闭时间 2026-07-09)
  • 部署方式:Self Hosted (Source)
  • Redis 服务:确认是否曾写入过非 UTF-8 数据(例如通过 raw Redis CLI、旧版本缓存、或其他非 Dify 进程)
  • Python 版本:检查 str.decode("utf-8") 的行为——Python 3 强校验 UTF-8,任何无效字节都会导致 UnicodeDecodeError

解决步骤

  1. 定位三个受影响的文件:api/core/helper/provider_cache.pyapi/core/helper/tool_parameter_cache.pyapi/core/helper/model_provider_cache.py
  2. 在每个文件的 get() 方法中,找到现有的 except (JSONDecodeError):except JSONDecodeError: 语句。
  3. UnicodeDecodeError 添加到异常捕获列表中,修改为:
except (JSONDecodeError, UnicodeDecodeError):
    return None

可优先尝试:如果无法立即修改代码,作为临时绕过方案,可以手动清除 Redis 中对应缓存的 key(例如 DEL <cache_key>),但这不能防止同一问题再次发生。推荐采用代码修复。

验证方法

执行最小单元测试来验证修复:

# 假设已有 mock 的 redis_client
redis_client.get.return_value = b"\xff"
result = cache.get()
assert result is None  # 修复后应返回 None,而非抛出异常

或者在 Dify 运行环境中,通过 Redis CLI 手动将一个缓存的值设置为无效字节(例如 SET <some_cache_key> \xff),然后触发相关业务逻辑(如模型配置加载、工具参数获取、提供者缓存刷新),观察是否不再崩溃而是正常回退。

参考来源

langgenius/dify #37834 – Bug: Redis cache helpers crash on invalid UTF-8 bytes

GamsGo AI

AI 工具推荐

想把多个 AI 模型放在一个入口?

GamsGo AI 集成 ChatGPT、DeepSeek、Gemini、Claude、Midjourney、Veo 等常用模型,适合写作、绘图、视频和日常 AI 工作流。

了解 GamsGo AI

推广链接:通过此链接购买,我可能获得佣金,不影响你的价格。

celebrityanime
celebrityanime
文章: 12185

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注