From d7e510763d83d6ed0cd9be6485212005caace07a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=90=B4=E6=97=AD=E4=BA=91?= Date: Wed, 25 Mar 2026 21:01:10 +0800 Subject: [PATCH] fix: add null checks for runtime.context and tighten langgraph constraint (#1326) - Add null checks for runtime.context in uploads_middleware.py and sandbox/middleware.py to prevent NPE when langgraph runtime context is None - Tighten langgraph version constraint from >=1.0.6 to >=1.0.6,<1.0.10 to avoid context=None incompatibility with langgraph-api 0.7.x Co-authored-by: Claude Opus 4.6 Co-authored-by: Willem Jiang --- .../deerflow/agents/middlewares/uploads_middleware.py | 2 +- backend/packages/harness/deerflow/sandbox/middleware.py | 6 ++++-- backend/packages/harness/pyproject.toml | 2 +- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/backend/packages/harness/deerflow/agents/middlewares/uploads_middleware.py b/backend/packages/harness/deerflow/agents/middlewares/uploads_middleware.py index dbd4727..d9cb5f8 100644 --- a/backend/packages/harness/deerflow/agents/middlewares/uploads_middleware.py +++ b/backend/packages/harness/deerflow/agents/middlewares/uploads_middleware.py @@ -146,7 +146,7 @@ class UploadsMiddleware(AgentMiddleware[UploadsMiddlewareState]): return None # Resolve uploads directory for existence checks - thread_id = runtime.context.get("thread_id") if runtime.context else None + thread_id = (runtime.context or {}).get("thread_id") 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 diff --git a/backend/packages/harness/deerflow/sandbox/middleware.py b/backend/packages/harness/deerflow/sandbox/middleware.py index caf6e46..deefc23 100644 --- a/backend/packages/harness/deerflow/sandbox/middleware.py +++ b/backend/packages/harness/deerflow/sandbox/middleware.py @@ -56,7 +56,9 @@ class SandboxMiddleware(AgentMiddleware[SandboxMiddlewareState]): # Eager initialization (original behavior) if "sandbox" not in state or state["sandbox"] is None: - thread_id = runtime.context["thread_id"] + thread_id = (runtime.context or {}).get("thread_id") + if thread_id is None: + return super().before_agent(state, runtime) sandbox_id = self._acquire_sandbox(thread_id) logger.info(f"Assigned sandbox {sandbox_id} to thread {thread_id}") return {"sandbox": {"sandbox_id": sandbox_id}} @@ -71,7 +73,7 @@ class SandboxMiddleware(AgentMiddleware[SandboxMiddlewareState]): get_sandbox_provider().release(sandbox_id) return None - if runtime.context and runtime.context.get("sandbox_id") is not None: + if (runtime.context or {}).get("sandbox_id") is not None: sandbox_id = runtime.context.get("sandbox_id") logger.info(f"Releasing sandbox {sandbox_id} from context") get_sandbox_provider().release(sandbox_id) diff --git a/backend/packages/harness/pyproject.toml b/backend/packages/harness/pyproject.toml index f8c5bfc..c5a31b9 100644 --- a/backend/packages/harness/pyproject.toml +++ b/backend/packages/harness/pyproject.toml @@ -13,7 +13,7 @@ dependencies = [ "langchain-deepseek>=1.0.1", "langchain-mcp-adapters>=0.1.0", "langchain-openai>=1.1.7", - "langgraph>=1.0.6", + "langgraph>=1.0.6,<1.0.10", "langgraph-api>=0.7.0,<0.8.0", "langgraph-cli>=0.4.14", "langgraph-runtime-inmem>=0.22.1",