MCP tools/call fails with closed transaction inside sessionmaker().begin() on 1.16.1

这个报错通常发生在 Dify 1.16.1 自托管环境中,通过 MCP 客户端对已发布应用调用 tools/call 时。MCP 控制器用 sessionmaker().begin() 包住了整个请求,而下游生成流程内部又执行了 session.commit(),导致事务被提前关闭。优先排查 api

快速结论:这个报错通常发生在 Dify 1.16.1 自托管环境中,通过 MCP 客户端对已发布应用调用 tools/call 时。MCP 控制器用 sessionmaker().begin() 包住了整个请求,而下游生成流程内部又执行了 session.commit(),导致事务被提前关闭。优先排查 api/controllers/mcp/mcp.py 中的会话管理方式。

适用环境:Dify 1.16.1,Self Hosted(Docker Compose),Python 3.12(由报错栈中的 python3.12 路径可确认);其余依赖版本 Issue 未明确。

最快修复方案:暂无确认的一步修复方案。Issue 评论中给出的可优先尝试的绕行方案是:把 api/controllers/mcp/mcp.py 中的 sessionmaker(…).begin() 上下文替换为普通 Session(db.engine, expire_on_commit=False)(即去掉 .begin()),并在末尾显式提交。

注意事项:该绕行方案来自评论分析,属于与 RAG 控制器修复(PR #36392、#36077)同类的处理模式,Issue 中未附上合并进主干的 PR,也未给出官方验证结果。应用前请自行确认对现有 MCP 控制器事务边界的影响,并注意会话生命周期与异常回滚。

问题场景

在 Dify 1.16.1(Docker Compose 自托管)中,创建一个 Chatflow 或 Workflow 应用并发布后,为该应用启用 MCP,拿到 MCP 服务端点(/mcp/server/<server_code>/mcp),再用 MCP 客户端连接该端点。initialize 和 tools/list 可能正常返回,但调用 tools/call 去实际执行已发布应用的工具时触发失败。API 日志显示异常发生在 MCP 的 streamable_http 处理链,向下进入 AppGenerateService.generate(),最终落到 advanced_chat/app_generator.py 中给 conversation.override_model_configs 赋值时,由 SQLAlchemy 抛出事务已关闭的错误。

报错原文

MCP error -32603: Internal server error
Can't operate on closed transaction inside context manager.
Please complete the context manager before emitting further commands.

2026-07-29 02:17:22.563 ERROR [Dummy-8] [streamable_http.py:138] ... - Internal server error
Traceback (most recent call last):
  File "/app/api/core/mcp/server/streamable_http.py", line 127, in handle_mcp_request
    handle_call_tool(session, app, request, user_input_form, end_user, protocol_version)
  File "/app/api/core/mcp/server/streamable_http.py", line 209, in handle_call_tool
    response = AppGenerateService.generate(
  File "/app/api/services/app_generate_service.py", line 112, in generate
    return cls._run_with_guardrails(
  ...
  File "/app/api/core/app/apps/advanced_chat/app_generator.py", line 558, in _generate
    conversation.override_model_configs = workflow.features
  ...
  File "/app/api/.venv/lib/python3.12/site-packages/sqlalchemy/orm/session.py", line 929, in __init__
    TransactionalContext._trans_ctx_check(session)
  File "/app/api/.venv/lib/python3.12/site-packages/sqlalchemy/engine/util.py", line 111, in _trans_ctx_check
    raise exc.InvalidRequestError(
sqlalchemy.exc.InvalidRequestError: Can't operate on closed transaction inside context manager. Please complete the context manager before emitting further commands.

原因分析

根据 Issue 正文与评论分析,根因是 api/controllers/mcp/mcp.py 用 sessionmaker().begin() 把整个请求包在上下文管理器里,该上下文在退出时会自动提交。当这个 session 被传递到下游的 AppGenerateService.generate() → advanced_chat/app_generator.py 时,生成代码路径内部又执行了 session.commit(),这会提前关闭事务。之后任何 ORM 变更(例如设置 conversation.override_model_configs)都会失败,因为 sessionmaker().begin() 的上下文管理器检测到它的事务已经被关闭。

评论指出这一行为由 PR #34281 引入,该 PR 将 MCP 控制器迁移到 sessionmaker().begin(),但没有考虑应用生成服务内部仍会调用 session.commit() 的情况。Issue 作者也指出这与 #39191 / #39223(dataset 路径,已在 1.16.1 修复但未覆盖 MCP)、#36392 / #36077(RAG 控制器,改用普通 Session)属于同一类问题;并且截至当前 main 分支,api/controllers/mcp/mcp.py 仍在使用 sessionmaker(…).begin(),尚无针对该 MCP 路径的修复 PR。另有用户在 #38998 报告了完全相同的 MCP 相关失败。

环境排查

  • 确认 Dify 版本是否为 1.16.1(Docker Compose 自托管部署)。
  • 确认报错栈中 Python 路径为 python3.12,即运行环境为 Python 3.12。
  • 确认应用类型为已发布的 Chatflow 或 Workflow,且已启用 MCP 并连接对应 MCP 端点。
  • 确认失败仅出现在 tools/call,而 initialize / tools/list 可能正常。
  • 检查 api/controllers/mcp/mcp.py 是否仍使用 sessionmaker(…).begin() 作为请求级会话管理。
  • CUDA、显卡、PyTorch 及具体依赖版本未在 Issue 中给出,如有环境差异需另行确认。

解决步骤

  1. 复现并定位:用 MCP 客户端对已发布应用调用 tools/call,确认返回 MCP error -32603,并在 API 日志中看到 sqlalchemy.exc.InvalidRequestError: Can’t operate on closed transaction inside context manager。
  2. 检查 api/controllers/mcp/mcp.py,确认请求处理是否被 sessionmaker(…).begin() 上下文包裹。
  3. 可优先尝试的绕行方案:将 sessionmaker(…).begin() 上下文替换为普通 Session(db.engine, expire_on_commit=False)(即去掉 .begin()),并在处理逻辑末尾显式提交。
  4. 这样下游生成流程内部的 session.commit() 不会与上下文管理器的自动提交冲突,从而避免事务被提前关闭。该模式与 RAG 控制器修复(PR #36392、#36077)一致。
  5. 关注 Issue #37403 这一涵盖约 153+ 文件的会话重构总览 Issue,以及是否出现针对 MCP 路径的正式修复 PR。

验证方法

应用绕行修改后,重启 API 服务,再次用 MCP 客户端连接同一端点,先调用 initialize / tools/list,再调用 tools/call。如果返回的是应用/工作流的正常结果,且 API 日志中不再出现 Can’t operate on closed transaction inside context manager 或 MCP error -32603,即可认为问题已解决。若仍失败,请核对下游生成服务是否还有其他内部 session.commit() 与当前会话管理方式冲突。

参考来源

langgenius/dify #39787

GamsGo AI

AI 工具推荐

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

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

了解 GamsGo AI

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

这个方案解决了吗?

celebrityanime
celebrityanime
文章: 23066

发表回复

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