From 46d0c329c1b9c975b877aeeb85c864e0baf273c1 Mon Sep 17 00:00:00 2001 From: SHIYAO ZHANG <834247613@qq.com> Date: Fri, 3 Apr 2026 20:26:21 +0800 Subject: [PATCH] fix(uploads): fall back to configurable.thread_id when runtime.context lacks thread_id (#1814) * fix(uploads): fall back to configurable.thread_id when runtime.context lacks thread_id runtime.context does not always carry thread_id depending on the LangGraph invocation path. When absent, uploads_dir resolved to None and the entire outline/historical-files attachment was silently skipped. Apply the same fallback pattern already used by ThreadDataMiddleware: try get_config().configurable.thread_id, with a RuntimeError guard for test environments where get_config() is called outside a runnable context. Discovered via live integration testing (curl against local LangGraph). Unit tests inject uploads_dir directly and would not catch this. * style: apply ruff format to uploads_middleware.py --- .../deerflow/agents/middlewares/uploads_middleware.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/backend/packages/harness/deerflow/agents/middlewares/uploads_middleware.py b/backend/packages/harness/deerflow/agents/middlewares/uploads_middleware.py index d9cb5f8b0..58468765a 100644 --- a/backend/packages/harness/deerflow/agents/middlewares/uploads_middleware.py +++ b/backend/packages/harness/deerflow/agents/middlewares/uploads_middleware.py @@ -147,6 +147,13 @@ class UploadsMiddleware(AgentMiddleware[UploadsMiddlewareState]): # Resolve uploads directory for existence checks thread_id = (runtime.context or {}).get("thread_id") + if thread_id is None: + try: + from langgraph.config import get_config + + thread_id = get_config().get("configurable", {}).get("thread_id") + except RuntimeError: + pass # get_config() raises outside a runnable context (e.g. unit tests) uploads_dir = self._paths.sandbox_uploads_dir(thread_id) if thread_id else None # Get newly uploaded files from the current message's additional_kwargs.files