快速结论:该问题出现在 Dify 的自托管源码环境中:在 Studio 应用列表或 Agents 列表中删除条目时,被删除的卡片及其“More”菜单会随列表刷新而消失,键盘焦点因此回落到文档 body,触发 “Deleting an app or agent can lose keyboard focus when its card disappears”。如果列表被过滤到只剩该条目,删除后结果为空,问题更易复现。优先排查焦点恢复目标和删除对话框的挂载生命周期。
适用环境:Dify 自托管源码检出(Source,提交 c8f98971aa);本地 vinext 开发服务器;Base UI 1.9.0;桌面版 Chrome。Studio 应用列表和 Agents 列表均复现。
最快修复方案:暂无确认的一步修复方案。Issue 中给出的修复思路是:让删除对话框跟随仍然存在的列表所有者(list owner)挂载,不再随被删卡片一起卸载;并为每次删除确认提供明确的返回焦点目标。在 Studio 侧,可通过 AlertDialogContent 透传的 Base UI Popup 属性设置 finalFocus;在 Agents 列表侧,列表组件已持有卡片之外的对话框,只需显式指定返回目标。
注意事项:以上是 Issue 讨论中提出的修复方向,修复代码尚未在讨论中确认合入并被验证,属于可优先尝试的方案。finalFocus 仅作用于这些删除流程,不改变共享 AlertDialog 原语的默认行为。回归验证应包含“零过渡动画”的真实关闭过程,因为退出动画可能掩盖查询刷新与焦点恢复之间的竞态。
问题场景
在 Dify Studio 或 Agents 页面中,用户新建一个临时条目,并把列表过滤到只剩该条目,然后用键盘操作该卡片“More”菜单中的 Delete,输入名称并确认删除。确认框关闭、卡片从列表消失后,键盘焦点丢失。Issue 报告者指出,Studio 中删除对话框和删除 mutation 都由卡片自身持有;当 Starred 条目的移除早于主目录刷新完成时,对话框会被提前卸载(premature unmount)。
报错原文
Deleting an app or agent can lose keyboard focus when its card disappears
原因分析
最直接的原因是:被删除卡片的操作按钮(即焦点来源)随卡片一起卸载,且没有仍然存在的焦点历史目标,焦点只能回落到 document.body。
另一个可能叠加的原因是删除后的刷新时序。Issue 评论指出,共享的应用删除 mutation 通过 Promise.all 等待 catalog、Starred 和 recent-app 三处失效刷新完成,而卡片在每次调用传入的 onSuccess 中关闭对话框。若 Starred 刷新更快,卡片会在其余刷新完成前先被移除,导致持有删除对话框的组件提前卸载,这也解释了报告者观察到的“premature-unmount”现象。该时序结论来自对源码的阅读与复现描述,属于可能原因,未在 Issue 中给出独立量化验证。
环境排查
- 确认 Dify 部署方式为源码自托管(Self Hosted, Source),而非云端。
- 确认源码提交处于或接近 c8f98971aa,以对齐问题复现条件。
- 确认依赖中的 Base UI 版本为 1.9.0。
- 确认使用本地 vinext 开发服务器。
- 在桌面版 Chrome 中复现,并使用键盘全程完成删除确认。
- 检查复现场景是否为“列表被过滤后删除导致结果为空”,该条件会放大焦点丢失概率。
- Issue 未提供 Python、CUDA、PyTorch、显卡等版本信息,无需作为排查项。
解决步骤
- 复现前先记录删除前的键盘焦点位置,确认焦点停留在被删卡片“More”菜单触发按钮上,便于对比修复前后差异。
- 将列表过滤到只剩待删除条目,再执行删除,确认删除后列表为空时是否出现焦点落到
document.body。 - 检查 Studio 中应用的删除对话框是否由卡片组件持有:如果是,它会在卡片卸载时一并卸载,需要把对话框移动到仍然存在的列表所有者层级上。
- 为成功删除设置每次确认对应的返回焦点目标。Studio 侧可利用
AlertDialogContent已透传的 Base UI Popup 属性传入finalFocus;Agents 列表侧的对话框已在卡片之外,需要显式提供该返回目标。 - 检查共享删除 mutation 的刷新时序:确认对话框关闭逻辑是否应等到
Promise.all中 catalog、Starred、recent 刷新完成后再执行,或至少避免在 Starred 提前移除卡片时关闭已卸载组件上的对话框。 - 取消删除的分支也需保持原有行为,即将焦点恢复到发起删除的卡片操作按钮上。
- 在回归测试中新增真实关闭且不使用退出动画的用例,避免动画掩盖刷新与焦点恢复之间的竞态。
验证方法
在桌面版 Chrome 中用键盘分别验证两个页面:一是 Studio 应用列表,二是 Agents 列表。将列表过滤到只剩一个条目后执行删除并确认删除成功,检查焦点是否落在稳定、有名称的列表区域上,且列表滚动位置没有变化;再执行一次取消删除,检查焦点是否回到原卡片的操作按钮。重复执行多次,确认刷新时序不同时焦点结果保持一致。对 Studio 还应验证 Starred 条目先于主目录刷新移除时,删除对话框不会被提前卸载。
参考来源
AI 工具推荐
想把多个 AI 模型放在一个入口?
GamsGo AI 集成 ChatGPT、DeepSeek、Gemini、Claude、Midjourney、Veo 等常用模型,适合写作、绘图、视频和日常 AI 工作流。
推广链接:通过此链接购买,我可能获得佣金,不影响你的价格。
这个方案解决了吗?
可以继续搜索完整报错,或查看同一工具的其他排查指南。

![[Usage]: DeepSeek-V4: --kv-cache-dtype auto fails silently on Blackwell SM120 — should auto-resolve to fp8_ds_mla](https://www.chat-gpts.plus/wp-content/uploads/2026/10/47174-09548d62-768x403.jpg)
