From df695e2c24035912849eb35ad0e8f98002b99811 Mon Sep 17 00:00:00 2001 From: Debug Agent Date: Wed, 1 Apr 2026 15:27:10 -0300 Subject: [PATCH 1/4] fix: always install Node 22 for ACP packages in agent-server images MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit SWE-bench base images often ship with NVM-managed old Node.js versions (v8–v14) that already have `npm` in PATH. The previous conditional install (`if ! command -v npm`) would skip Node 22, causing ACP packages (claude-agent-acp, codex-acp, gemini-cli) to be installed into the old Node.js where they crash with SyntaxError on modern ES module syntax. Remove the conditional and always install Node 22 from nodesource so ACP subprocess servers can start reliably regardless of the base image. Fixes: OpenHands/runtime-api#458 Co-Authored-By: Claude Opus 4.6 --- .../openhands/agent_server/docker/Dockerfile | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/openhands-agent-server/openhands/agent_server/docker/Dockerfile b/openhands-agent-server/openhands/agent_server/docker/Dockerfile index b857f7b221..976280c918 100644 --- a/openhands-agent-server/openhands/agent_server/docker/Dockerfile +++ b/openhands-agent-server/openhands/agent_server/docker/Dockerfile @@ -93,13 +93,13 @@ RUN set -eux; \ rm -rf /var/lib/apt/lists/* # Pre-install ACP servers for ACPAgent support (Claude Code, Codex, Gemini CLI) -# Install Node.js/npm if not present (SWE-bench base images may lack them) +# Always install Node.js 22+ even if an older version exists (e.g. SWE-bench +# images ship NVM-managed Node 8-14 which cannot run modern ACP packages). RUN set -eux; \ - if ! command -v npm >/dev/null 2>&1; then \ - curl -fsSL https://deb.nodesource.com/setup_22.x | bash - && \ - apt-get install -y --no-install-recommends nodejs && \ - rm -rf /var/lib/apt/lists/*; \ - fi; \ + curl -fsSL https://deb.nodesource.com/setup_22.x | bash - && \ + apt-get install -y --no-install-recommends nodejs && \ + rm -rf /var/lib/apt/lists/* && \ + node --version && \ npm install -g @zed-industries/claude-agent-acp @zed-industries/codex-acp @google/gemini-cli # Configure Claude Code managed settings for headless operation: From 68c2537e28a85c7f3a1ade884b9a30e63fdc9797 Mon Sep 17 00:00:00 2001 From: Debug Agent Date: Wed, 1 Apr 2026 17:35:06 -0300 Subject: [PATCH 2/4] fix: install Node 22 to dedicated prefix to avoid breaking repo tests Instead of replacing the system Node.js with nodesource, download a Node 22 binary tarball to /opt/acp-node/ and install ACP packages there. Wrapper scripts in /usr/local/bin/ prepend the ACP Node to PATH only for the ACP subprocess, so the repo's own Node.js (needed for test suites) stays untouched. Co-Authored-By: Claude Opus 4.6 --- .../openhands/agent_server/docker/Dockerfile | 32 +++++++++++++++---- 1 file changed, 25 insertions(+), 7 deletions(-) diff --git a/openhands-agent-server/openhands/agent_server/docker/Dockerfile b/openhands-agent-server/openhands/agent_server/docker/Dockerfile index 976280c918..6021048d27 100644 --- a/openhands-agent-server/openhands/agent_server/docker/Dockerfile +++ b/openhands-agent-server/openhands/agent_server/docker/Dockerfile @@ -93,14 +93,32 @@ RUN set -eux; \ rm -rf /var/lib/apt/lists/* # Pre-install ACP servers for ACPAgent support (Claude Code, Codex, Gemini CLI) -# Always install Node.js 22+ even if an older version exists (e.g. SWE-bench -# images ship NVM-managed Node 8-14 which cannot run modern ACP packages). +# Install Node.js 22 to a dedicated prefix so ACP packages get a modern runtime +# WITHOUT overwriting the repo-specific Node.js that test suites depend on. +# SWE-bench images ship NVM/apt-managed Node 8-14 which cannot run ACP packages. +ENV ACP_NODE_DIR=/opt/acp-node RUN set -eux; \ - curl -fsSL https://deb.nodesource.com/setup_22.x | bash - && \ - apt-get install -y --no-install-recommends nodejs && \ - rm -rf /var/lib/apt/lists/* && \ - node --version && \ - npm install -g @zed-industries/claude-agent-acp @zed-industries/codex-acp @google/gemini-cli + ARCH=$(dpkg --print-architecture); \ + case "$ARCH" in amd64) NARCH=x64;; arm64) NARCH=arm64;; *) NARCH=$ARCH;; esac; \ + mkdir -p "$ACP_NODE_DIR"; \ + curl -fsSL "https://nodejs.org/dist/v22.14.0/node-v22.14.0-linux-${NARCH}.tar.xz" \ + | tar -xJ --strip-components=1 -C "$ACP_NODE_DIR"; \ + "$ACP_NODE_DIR/bin/node" --version; \ + "$ACP_NODE_DIR/bin/npm" install -g \ + @zed-industries/claude-agent-acp \ + @zed-industries/codex-acp \ + @google/gemini-cli; \ + # Create wrappers in /usr/local/bin that prepend ACP's Node 22 to PATH. + # This ensures the ACP binary's #!/usr/bin/env node shebang resolves to + # Node 22, while the repo's own node (NVM/system) stays untouched for tests. + for bin in claude-agent-acp codex-acp gemini; do \ + if [ -e "$ACP_NODE_DIR/bin/$bin" ]; then \ + printf '#!/bin/sh\nPATH="%s/bin:$PATH" exec "%s/bin/%s" "$@"\n' \ + "$ACP_NODE_DIR" "$ACP_NODE_DIR" "$bin" \ + > /usr/local/bin/"$bin"; \ + chmod +x /usr/local/bin/"$bin"; \ + fi; \ + done # Configure Claude Code managed settings for headless operation: # Allow all tool permissions (no human in the loop to approve). From d6da0342c5f8fc25f90411cc877d53b155ca5faa Mon Sep 17 00:00:00 2001 From: Debug Agent Date: Wed, 1 Apr 2026 18:26:04 -0300 Subject: [PATCH 3/4] fix: increase APIRemoteWorkspace api_timeout from 60s to 600s The POST /api/conversations request triggers lazy agent initialization (ACP subprocess startup, model config loading, tool registration) which routinely takes >60s on heavy SWE-bench multimodal images. The 60s default caused httpx.ReadTimeout on 4/5 test instances even after the Node.js fix landed. Align with the parent RemoteWorkspace.read_timeout default (600s) and the legacy code which used 120-600s for this value. Co-Authored-By: Claude Opus 4.6 --- .../openhands/workspace/remote_api/workspace.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/openhands-workspace/openhands/workspace/remote_api/workspace.py b/openhands-workspace/openhands/workspace/remote_api/workspace.py index 13cc332401..06a9d9c45a 100644 --- a/openhands-workspace/openhands/workspace/remote_api/workspace.py +++ b/openhands-workspace/openhands/workspace/remote_api/workspace.py @@ -70,7 +70,11 @@ class APIRemoteWorkspace(RemoteWorkspace): gt=0, ) api_timeout: float = Field( - default=60.0, description="API request timeout (seconds)" + default=600.0, + description="Timeout in seconds for reading HTTP responses from the " + "agent-server. Must be long enough for conversation creation, which " + "triggers lazy agent initialisation (ACP subprocess startup, model " + "config loading, etc.).", ) keep_alive: bool = Field(default=False, description="Keep runtime alive on cleanup") pause_on_close: bool = Field( From 84aaf0d29d81472471e9b1df69e77908e63a0529 Mon Sep 17 00:00:00 2001 From: Debug Agent Date: Wed, 1 Apr 2026 18:26:57 -0300 Subject: [PATCH 4/4] Revert "fix: increase APIRemoteWorkspace api_timeout from 60s to 600s" This reverts commit d6da0342c5f8fc25f90411cc877d53b155ca5faa. --- .../openhands/workspace/remote_api/workspace.py | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/openhands-workspace/openhands/workspace/remote_api/workspace.py b/openhands-workspace/openhands/workspace/remote_api/workspace.py index 06a9d9c45a..13cc332401 100644 --- a/openhands-workspace/openhands/workspace/remote_api/workspace.py +++ b/openhands-workspace/openhands/workspace/remote_api/workspace.py @@ -70,11 +70,7 @@ class APIRemoteWorkspace(RemoteWorkspace): gt=0, ) api_timeout: float = Field( - default=600.0, - description="Timeout in seconds for reading HTTP responses from the " - "agent-server. Must be long enough for conversation creation, which " - "triggers lazy agent initialisation (ACP subprocess startup, model " - "config loading, etc.).", + default=60.0, description="API request timeout (seconds)" ) keep_alive: bool = Field(default=False, description="Keep runtime alive on cleanup") pause_on_close: bool = Field(