bug: Historical terminal file cards depend on composer selection

该报错通常出现在 Open WebUI 聊天记录中查看历史 Open Terminal 文件卡片(如 XLSX、DOCX)时,若当前 composer 没有选中卡片所属的终端,卡片就会显示 Terminal unavailable ;优先排查卡片关联的 terminal 是否仍在当前用户可访问的终端

快速结论:该报错通常出现在 Open WebUI 聊天记录中查看历史 Open Terminal 文件卡片(如 XLSX、DOCX)时,若当前 composer 没有选中卡片所属的终端,卡片就会显示 Terminal unavailable;优先排查卡片关联的 terminal 是否仍在当前用户可访问的终端列表中,以及前端是否错误地依赖了 composer 的当前选择。

适用环境:Open WebUI v0.11.3(当前 dev 也受影响);Docker 安装;Linux;Chrome 149。Issue 明确涉及系统级 Open Terminal(system-level terminal),不涉及 direct-terminal URL 问题。

最快修复方案:暂无确认的一步修复方案。Issue 最终被报告者自行关闭,关闭原因是修正复现后无法在未修改的 v0.11.3 上复现同用户行为;因此没有已验证的代码级修复步骤。

注意事项:报告者最初观察到的失败实际发生在管理员通过 /s/<chat-id> 路由查看其他用户聊天时,而不是终端工作区所有者在正常 /c/... 聊天中查看自己的对话。Open Terminal 多用户工作区按用户隔离,跨用户访问的“不可用”可能属于预期隔离行为,而不一定是同用户场景下的 bug。

问题场景

用户在 Open WebUI 的聊天记录中查看此前由 Open Terminal 生成的文件卡片,例如 XLSX 或 DOCX 预览卡片。复现路径是:先选中一个系统 Open Terminal 连接,在聊天中创建并显示文件,确认卡片能正常渲染;然后清除 localStorage.selectedTerminalId 并重新加载聊天;此时历史卡片显示 Terminal unavailable。再次选中同一个终端后,卡片无需重新创建文件即可立即渲染。

Issue 正文认为问题出在前端组件 src/lib/components/chat/Messages/TerminalOutputFile.svelte 中的选择检查逻辑:历史卡片本应根据自身保存的 terminal_selector 解析终端,而不是依赖 composer 当前选中的终端。

报错原文

Terminal unavailable

Issue 中引用的前端 guard 代码:

if (!selector || $selectedTerminalId !== selector) return null;

Issue 还指出,仅移除选择检查并不足够,因为:

$: terminal = resolveTerminal();

没有响应式依赖,只会在挂载时解析一次。如果此时 $terminalServers 仍为 null,卡片会一直不可用。terminal 需要依赖 selector$terminalServers$settings

此外,direct terminal 仍与选择绑定:Chat.svelte 只为当前选中的 direct terminal 设置 enabled,而查找逻辑要求 server.enabled。不过本 Issue 报告的是 system terminal,不涉及 direct terminal。

原因分析

可能原因一:历史文件卡片渲染时错误地要求 composer 当前选中的终端与卡片保存的 terminal_selector 一致。当 composer 没有选择终端,或选择被清除后,guard 在发起任何请求之前就返回 null,导致卡片显示 Terminal unavailable。Issue 中提到,正常工作的卡片会通过 /api/v1/terminals/<terminal-id>/files/view 请求文件;而 composer 选择为空时,guard 在请求之前就返回了。

可能原因二:即使移除选择检查,resolveTerminal() 也只会在挂载时解析一次;如果当时 $terminalServers 仍为 null,卡片仍然无法解析终端。Issue 认为需要让 terminal 依赖 selector$terminalServers$settings

需要注意:Issue 最终由报告者关闭,原因是修正复现后发现,最初观察到的失败发生在管理员通过 /s/<chat-id> 查看其他用户聊天时,而非终端工作区所有者在正常 /c/... 聊天中的同用户场景。报告者在未修改的 v0.11.3 上重新测试所属账号后,XLSX 预览在刷新后可以正常渲染,因此无法复现同用户行为。该问题是否确实存在于同用户场景,尚未在 Issue 中确认。

环境排查

  • Open WebUI 版本:确认是否为 v0.11.3 或当前 dev;Issue 表示当前 dev 也受影响。
  • 安装方式:确认是否为 Docker 安装。
  • 操作系统:确认是否为 Linux。
  • 浏览器:确认是否为 Chrome 149,或是否存在浏览器扩展干扰。
  • 终端类型:确认使用的是系统级 Open Terminal,还是 direct terminal。Issue 明确指出本报告覆盖 system terminal,不涉及 #27621 的 direct-terminal URL 问题。
  • 用户与路由:确认当前查看聊天的是终端工作区所有者本人,还是管理员通过 /s/<chat-id> 查看其他用户的聊天。Issue 关闭时指出,跨用户查看时 Open Terminal 多用户工作区按用户隔离。
  • 前端状态:检查 localStorage.selectedTerminalId 是否为空,以及 composer 当前选中的终端是否与卡片保存的终端一致。
  • 组件逻辑:检查 src/lib/components/chat/Messages/TerminalOutputFile.svelte 中是否存在 if (!selector || $selectedTerminalId !== selector) return null; 这一 guard,以及 resolveTerminal() 是否具有响应式依赖。

解决步骤

  1. 先确认复现场景是否属于同用户场景。使用终端工作区所有者账号,在正常 /c/... 聊天中打开历史文件卡片,而不是使用管理员通过 /s/<chat-id> 查看其他用户聊天。Issue 关闭时明确指出,跨用户查看时 Open Terminal 多用户工作区按用户隔离,原报告者无法在同用户、未修改的 v0.11.3 上复现。
  2. 如果确实只在跨用户查看时出现 Terminal unavailable,不要将其视为同用户历史卡片 bug;这可能是多用户隔离带来的预期行为。可优先尝试用所属账号在正常聊天路由中验证。
  3. 如果同用户场景也能稳定复现,先记录当前 localStorage.selectedTerminalId 的值,并清除后重新加载聊天,确认卡片是否仍然显示 Terminal unavailable
  4. 再次选中卡片所属的终端,确认卡片是否立即恢复渲染。Issue 提到,选中同一个终端后,卡片无需重新创建文件即可渲染。
  5. 检查 TerminalOutputFile.svelte 中的 guard。Issue 指出当前 dev 含有 if (!selector || $selectedTerminalId !== selector) return null;,该逻辑会在 composer 未选中终端时提前返回。
  6. 不要只删除选择检查。Issue 明确说明仅移除选择检查不够:$: terminal = resolveTerminal(); 没有响应式依赖,若挂载时 $terminalServers 仍为 null,卡片仍可能不可用。需要考虑让 terminal 依赖 selector$terminalServers$settings
  7. 如果使用 direct terminal,请注意 Chat.svelte 只为当前选中的 direct terminal 设置 enabled,查找逻辑要求 server.enabled;本 Issue 不覆盖 direct terminal 的修复。

验证方法

使用终端工作区所有者账号,在正常 /c/... 聊天中打开包含历史 XLSX 或 DOCX 文件卡片的对话。清除 localStorage.selectedTerminalId 并重新加载页面,观察卡片是否仍显示 Terminal unavailable。如果卡片能够在不依赖 composer 当前选择的情况下正常渲染,说明同用户场景下的问题已解决。若只在管理员通过 /s/<chat-id> 查看其他用户聊天时出现,则更可能是多用户隔离行为,而不是同用户历史卡片渲染 bug。

参考来源

open-webui/open-webui #30071

GamsGo AI

AI 工具推荐

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

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

了解 GamsGo AI

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

这个方案解决了吗?

celebrityanime
celebrityanime
文章: 23916

发表回复

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