Chat attachments submit filename instead of file ID

该报错发生在 LobeChat 自托管 Docker/数据库版中,上传成功后发送带附件消息时,`messages_files.file_id` 误存为文件名(如 `image.png`)而不是数据库返回的 `file_*` ID。优先检查发送消息前 `chatUploadFileList` 中每个条

快速结论:该报错发生在 LobeChat 自托管 Docker/数据库版中,上传成功后发送带附件消息时,`messages_files.file_id` 误存为文件名(如 `image.png`)而不是数据库返回的 `file_*` ID。优先检查发送消息前 `chatUploadFileList` 中每个条目的 `id` 是否已从临时文件名更新为真实文件 ID。

适用环境:LobeChat 自托管 Docker/数据库版、S3 兼容存储(RustFS)、PostgreSQL、Web UI。Issue 未提供 Python、CUDA、显卡等信息,不补写。

最快修复方案:暂无确认的一步修复方案。Issue 中仅有一个临时 workaround——在数据库中创建触发器,将文件名解析为用户最新的 `files.id`,但作者已明确指出这仅是短期方案,根本修复应在客户端/服务端文件元数据流中完成。

注意事项:该触发器方案未在官方代码中验证,且仅适用于自托管数据库版;若多个文件同名,触发器可能解析到错误文件。根本修复需等待上游代码更新,确保 `fileService.createFile` 返回的真实 `data.id` 在用户发送前始终写入 store。

问题场景

用户在 LobeChat 自托管 Docker/数据库版中,配置 S3 兼容存储(RustFS)后,在聊天或 Home 输入框上传图片或 JSON 文件。文件上传成功并写入 `files` 表,但发送带附件消息时失败,因为客户端将原始文件名(如 `image.png`、`layout.json`)作为 `messages_files.file_id` 提交,而不是数据库返回的 `file_*` ID。

报错原文

insert into "messages_files" ("file_id", "message_id", "user_id", "workspace_id")
values ($1, $2, $3, $4)
params: image.png, <message_id>, <user_id>, <workspace_id>

/* 对应 files 表记录 */
file_QDNZEkaZQ4GH | image.png | files/<user>/...png

Chat attachments submit filename instead of file ID

原因分析

可能原因:这是纯客户端状态管理问题,与 S3/RustFS 存储层无关。具体链路如下:

  • 上传时,每个文件以 file.name(文件名)作为临时 ID 加入 `chatUploadFileList` 状态。
  • 上传完成后,`uploadWithProgress` 会通过 `updateFile` action 将真实 `file_*` ID 合并进 store。
  • 但有两种情况会导致真实 ID 永远未写入:
    store 查找未命中:如果以 `file.name` 为 key 的条目在成功回调触发前被移除或修改,reducer 找不到目标条目,真实 ID 就不会被写入。
    竞态条件:用户在 `status: ‘success’` dispatch 完成前就发送了消息,此时条目仍持有文件名,`files.map(f => f.id)` 返回的自然是文件名。

环境排查

  • 确认 LobeChat 为自托管 Docker/数据库版,且使用 S3 兼容存储(RustFS)和 PostgreSQL。
  • 在发送消息前,通过 console.log 或 Zustand devtools 打印完整 `chatUploadFileList`,核对每个条目的 `id` 是否已从文件名更新为 `file_*` ID。
  • 检查是否两个文件同名(如都叫 `image.png`),这会导致 dispatch 只更新第一个匹配项。

解决步骤

  1. 复现问题:按 Issue 中步骤上传图片或 JSON 文件,等待上传完成后添加文本并发送,观察插入 `messages_files` 时 `file_id` 的值。
  2. 确认状态:在发送前打印 `chatUploadFileList`,确认每个条目的 `id` 字段是文件名还是 `file_*` ID。若仍是文件名,说明真实 ID 未成功合并。
  3. 检查 dispatch:核对 `dispatchChatUploadFileList` 是否正确定位到目标条目。若两个文件同名,只有一个会被更新——可尝试上传不同名文件验证。
  4. 临时 workaround(仅限自托管数据库版):在 PostgreSQL 中创建触发器,将文件名解析为用户最新的 `files.id`。注意:这仅是短期方案,且同名文件可能解析错误。
  5. 等待上游修复:Issue 已确认是客户端状态管理问题,官方应确保 `fileService.createFile` 返回的真实 `data.id` 在用户发送前始终写入 store。可关注 LobeChat 后续版本更新。

验证方法

上传文件后,在发送消息前检查 `chatUploadFileList` 中条目 `id` 是否为 `file_*` 格式;发送成功后查询 `messages_files` 表,确认 `file_id` 字段存储的是数据库文件 ID 而非文件名。若不再出现外键/无效文件引用错误,且数据库插入成功,则问题已解决。

参考来源

lobehub/lobe-chat #18319

GamsGo AI

AI 工具推荐

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

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

了解 GamsGo AI

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

这个方案解决了吗?

celebrityanime
celebrityanime
文章: 18489

发表回复

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