From 0a8d2b6200f635f38ce987446b5ede6ba0d7bad7 Mon Sep 17 00:00:00 2001 From: Altay Date: Thu, 12 Mar 2026 15:24:54 +0300 Subject: [PATCH] build: raise Node 22 compatibility floor to 22.16 --- docs/index.md | 2 +- docs/install/ansible.md | 2 +- docs/install/bun.md | 2 +- docs/install/index.md | 4 ++-- docs/install/installer.md | 2 +- docs/install/node.md | 4 ++-- docs/platforms/linux.md | 2 +- docs/platforms/mac/bundled-gateway.md | 2 +- docs/platforms/mac/signing.md | 2 +- docs/reference/RELEASING.md | 2 +- docs/start/getting-started.md | 2 +- package.json | 2 +- scripts/install.sh | 2 +- src/daemon/runtime-paths.test.ts | 20 ++++++++++---------- src/infra/runtime-guard.test.ts | 14 +++++++------- src/infra/runtime-guard.ts | 4 ++-- src/memory/embeddings.ts | 2 +- 17 files changed, 35 insertions(+), 35 deletions(-) diff --git a/docs/index.md b/docs/index.md index 4c5530e9c2a..7c69600f55d 100644 --- a/docs/index.md +++ b/docs/index.md @@ -54,7 +54,7 @@ OpenClaw is a **self-hosted gateway** that connects your favorite chat apps — - **Agent-native**: built for coding agents with tool use, sessions, memory, and multi-agent routing - **Open source**: MIT licensed, community-driven -**What do you need?** Node 24 (recommended), or Node 22.12+ for compatibility, an API key from your chosen provider, and 5 minutes. For best quality and security, use the strongest latest-generation model available. +**What do you need?** Node 24 (recommended), or Node 22 LTS (`22.16+`) for compatibility, an API key from your chosen provider, and 5 minutes. For best quality and security, use the strongest latest-generation model available. ## How it works diff --git a/docs/install/ansible.md b/docs/install/ansible.md index 752b108bf11..63c18bec237 100644 --- a/docs/install/ansible.md +++ b/docs/install/ansible.md @@ -46,7 +46,7 @@ The Ansible playbook installs and configures: 1. **Tailscale** (mesh VPN for secure remote access) 2. **UFW firewall** (SSH + Tailscale ports only) 3. **Docker CE + Compose V2** (for agent sandboxes) -4. **Node.js 24 + pnpm** (runtime dependencies; Node `22.12+` remains supported for compatibility) +4. **Node.js 24 + pnpm** (runtime dependencies; Node 22 LTS, currently `22.16+`, remains supported for compatibility) 5. **OpenClaw** (host-based, not containerized) 6. **Systemd service** (auto-start with security hardening) diff --git a/docs/install/bun.md b/docs/install/bun.md index b8b0ef169f9..5cbe76ce3ac 100644 --- a/docs/install/bun.md +++ b/docs/install/bun.md @@ -45,7 +45,7 @@ bun run vitest run Bun may block dependency lifecycle scripts unless explicitly trusted (`bun pm untrusted` / `bun pm trust`). For this repo, the commonly blocked scripts are not required: -- `@whiskeysockets/baileys` `preinstall`: checks Node major >= 20 (OpenClaw defaults to Node 24 and still supports Node `22.12+`). +- `@whiskeysockets/baileys` `preinstall`: checks Node major >= 20 (OpenClaw defaults to Node 24 and still supports Node 22 LTS, currently `22.16+`). - `protobufjs` `postinstall`: emits warnings about incompatible version schemes (no build artifacts). If you hit a real runtime issue that requires these scripts, trust them explicitly: diff --git a/docs/install/index.md b/docs/install/index.md index b132356234b..d0f847838d0 100644 --- a/docs/install/index.md +++ b/docs/install/index.md @@ -13,7 +13,7 @@ Already followed [Getting Started](/start/getting-started)? You're all set — t ## System requirements -- **[Node 24 (recommended)](/install/node)** (`22.12+` is still supported for compatibility; the [installer script](#install-methods) will install Node 24 if missing) +- **[Node 24 (recommended)](/install/node)** (Node 22 LTS, currently `22.16+`, is still supported for compatibility; the [installer script](#install-methods) will install Node 24 if missing) - macOS, Linux, or Windows - `pnpm` only if you build from source @@ -70,7 +70,7 @@ For VPS/cloud hosts, avoid third-party "1-click" marketplace images when possibl - If you already manage Node yourself, we recommend Node 24. OpenClaw still supports Node `22.12+` for compatibility: + If you already manage Node yourself, we recommend Node 24. OpenClaw still supports Node 22 LTS, currently `22.16+`, for compatibility: diff --git a/docs/install/installer.md b/docs/install/installer.md index 1186d97fc7c..2ab4bc4a8b4 100644 --- a/docs/install/installer.md +++ b/docs/install/installer.md @@ -71,7 +71,7 @@ Recommended for most interactive installs on macOS/Linux/WSL. Supports macOS and Linux (including WSL). If macOS is detected, installs Homebrew if missing. - Checks Node version and installs Node 24 if needed (Homebrew on macOS, NodeSource setup scripts on Linux apt/dnf/yum). OpenClaw still supports Node `22.12+` for compatibility. + Checks Node version and installs Node 24 if needed (Homebrew on macOS, NodeSource setup scripts on Linux apt/dnf/yum). OpenClaw still supports Node 22 LTS, currently `22.16+`, for compatibility. Installs Git if missing. diff --git a/docs/install/node.md b/docs/install/node.md index 349333f9f24..9cf2f59ec77 100644 --- a/docs/install/node.md +++ b/docs/install/node.md @@ -9,7 +9,7 @@ read_when: # Node.js -OpenClaw requires **Node 22.12 or newer**. **Node 24 is the default and recommended runtime** for installs, CI, and release workflows. The [installer script](/install#install-methods) will detect and install Node automatically — this page is for when you want to set up Node yourself and make sure everything is wired up correctly (versions, PATH, global installs). +OpenClaw requires **Node 22.16 or newer**. **Node 24 is the default and recommended runtime** for installs, CI, and release workflows. Node 22 remains supported via the active LTS line. The [installer script](/install#install-methods) will detect and install Node automatically — this page is for when you want to set up Node yourself and make sure everything is wired up correctly (versions, PATH, global installs). ## Check your version @@ -17,7 +17,7 @@ OpenClaw requires **Node 22.12 or newer**. **Node 24 is the default and recommen node -v ``` -If this prints `v24.x.x` or higher, you're on the recommended default. If it prints `v22.12.x` or higher, OpenClaw is still supported, but we recommend upgrading to Node 24 when convenient. If Node isn't installed or the version is too old, pick an install method below. +If this prints `v24.x.x` or higher, you're on the recommended default. If it prints `v22.16.x` or higher, you're on the supported Node 22 LTS path, but we still recommend upgrading to Node 24 when convenient. If Node isn't installed or the version is too old, pick an install method below. ## Install Node diff --git a/docs/platforms/linux.md b/docs/platforms/linux.md index 60161eaba4b..c03dba6f795 100644 --- a/docs/platforms/linux.md +++ b/docs/platforms/linux.md @@ -15,7 +15,7 @@ Native Linux companion apps are planned. Contributions are welcome if you want t ## Beginner quick path (VPS) -1. Install Node 24 (recommended; Node `22.12+` still works for compatibility) +1. Install Node 24 (recommended; Node 22 LTS, currently `22.16+`, still works for compatibility) 2. `npm i -g openclaw@latest` 3. `openclaw onboard --install-daemon` 4. From your laptop: `ssh -N -L 18789:127.0.0.1:18789 @` diff --git a/docs/platforms/mac/bundled-gateway.md b/docs/platforms/mac/bundled-gateway.md index 247afeb7b51..e6e57cc1809 100644 --- a/docs/platforms/mac/bundled-gateway.md +++ b/docs/platforms/mac/bundled-gateway.md @@ -16,7 +16,7 @@ running (or attaches to an existing local Gateway if one is already running). ## Install the CLI (required for local mode) -Node 24 is the default runtime on the Mac. Node `22.12+` still works for compatibility. Then install `openclaw` globally: +Node 24 is the default runtime on the Mac. Node 22 LTS, currently `22.16+`, still works for compatibility. Then install `openclaw` globally: ```bash npm install -g openclaw@ diff --git a/docs/platforms/mac/signing.md b/docs/platforms/mac/signing.md index aee3dfc8839..0feac8cd281 100644 --- a/docs/platforms/mac/signing.md +++ b/docs/platforms/mac/signing.md @@ -14,7 +14,7 @@ This app is usually built from [`scripts/package-mac-app.sh`](https://github.com - calls [`scripts/codesign-mac-app.sh`](https://github.com/openclaw/openclaw/blob/main/scripts/codesign-mac-app.sh) to sign the main binary and app bundle so macOS treats each rebuild as the same signed bundle and keeps TCC permissions (notifications, accessibility, screen recording, mic, speech). For stable permissions, use a real signing identity; ad-hoc is opt-in and fragile (see [macOS permissions](/platforms/mac/permissions)). - uses `CODESIGN_TIMESTAMP=auto` by default; it enables trusted timestamps for Developer ID signatures. Set `CODESIGN_TIMESTAMP=off` to skip timestamping (offline debug builds). - inject build metadata into Info.plist: `OpenClawBuildTimestamp` (UTC) and `OpenClawGitCommit` (short hash) so the About pane can show build, git, and debug/release channel. -- **Packaging defaults to Node 24**: the script runs TS builds and the Control UI build. Node `22.12+` remains supported for compatibility. +- **Packaging defaults to Node 24**: the script runs TS builds and the Control UI build. Node 22 LTS, currently `22.16+`, remains supported for compatibility. - reads `SIGN_IDENTITY` from the environment. Add `export SIGN_IDENTITY="Apple Development: Your Name (TEAMID)"` (or your Developer ID Application cert) to your shell rc to always sign with your cert. Ad-hoc signing requires explicit opt-in via `ALLOW_ADHOC_SIGNING=1` or `SIGN_IDENTITY="-"` (not recommended for permission testing). - runs a Team ID audit after signing and fails if any Mach-O inside the app bundle is signed by a different Team ID. Set `SKIP_TEAM_ID_CHECK=1` to bypass. diff --git a/docs/reference/RELEASING.md b/docs/reference/RELEASING.md index cbd77385b93..f929d16e5f7 100644 --- a/docs/reference/RELEASING.md +++ b/docs/reference/RELEASING.md @@ -9,7 +9,7 @@ read_when: # Release Checklist (npm + macOS) -Use `pnpm` from the repo root with Node 24 by default. Node `22.12+` remains supported for compatibility. Keep the working tree clean before tagging/publishing. +Use `pnpm` from the repo root with Node 24 by default. Node 22 LTS, currently `22.16+`, remains supported for compatibility. Keep the working tree clean before tagging/publishing. ## Operator trigger diff --git a/docs/start/getting-started.md b/docs/start/getting-started.md index 76a042825a2..26b54b63f6f 100644 --- a/docs/start/getting-started.md +++ b/docs/start/getting-started.md @@ -19,7 +19,7 @@ Docs: [Dashboard](/web/dashboard) and [Control UI](/web/control-ui). ## Prereqs -- Node 24 recommended (`22.12+` still supported for compatibility) +- Node 24 recommended (Node 22 LTS, currently `22.16+`, still supported for compatibility) Check your Node version with `node --version` if you are unsure. diff --git a/package.json b/package.json index 9c1100bc49f..b27e8247b5c 100644 --- a/package.json +++ b/package.json @@ -420,7 +420,7 @@ "node-llama-cpp": "3.16.2" }, "engines": { - "node": ">=22.12.0" + "node": ">=22.16.0" }, "packageManager": "pnpm@10.23.0", "pnpm": { diff --git a/scripts/install.sh b/scripts/install.sh index 8c83c70f67b..eb81d41deb0 100755 --- a/scripts/install.sh +++ b/scripts/install.sh @@ -18,7 +18,7 @@ NC='\033[0m' # No Color DEFAULT_TAGLINE="All your chats, one OpenClaw." NODE_DEFAULT_MAJOR=24 NODE_MIN_MAJOR=22 -NODE_MIN_MINOR=12 +NODE_MIN_MINOR=16 NODE_MIN_VERSION="${NODE_MIN_MAJOR}.${NODE_MIN_MINOR}" ORIGINAL_PATH="${PATH:-}" diff --git a/src/daemon/runtime-paths.test.ts b/src/daemon/runtime-paths.test.ts index 3b502193a33..0483d994f64 100644 --- a/src/daemon/runtime-paths.test.ts +++ b/src/daemon/runtime-paths.test.ts @@ -56,7 +56,7 @@ describe("resolvePreferredNodePath", () => { const execFile = vi .fn() .mockResolvedValueOnce({ stdout: "18.0.0\n", stderr: "" }) // execPath too old - .mockResolvedValueOnce({ stdout: "22.12.0\n", stderr: "" }); // system node ok + .mockResolvedValueOnce({ stdout: "22.16.0\n", stderr: "" }); // system node ok const result = await resolvePreferredNodePath({ env: {}, @@ -73,7 +73,7 @@ describe("resolvePreferredNodePath", () => { it("ignores execPath when it is not node", async () => { mockNodePathPresent(darwinNode); - const execFile = vi.fn().mockResolvedValue({ stdout: "22.12.0\n", stderr: "" }); + const execFile = vi.fn().mockResolvedValue({ stdout: "22.16.0\n", stderr: "" }); const result = await resolvePreferredNodePath({ env: {}, @@ -93,8 +93,8 @@ describe("resolvePreferredNodePath", () => { it("uses system node when it meets the minimum version", async () => { mockNodePathPresent(darwinNode); - // Node 22.12.0+ is the minimum required version - const execFile = vi.fn().mockResolvedValue({ stdout: "22.12.0\n", stderr: "" }); + // Node 22.16.0+ is the minimum required version + const execFile = vi.fn().mockResolvedValue({ stdout: "22.16.0\n", stderr: "" }); const result = await resolvePreferredNodePath({ env: {}, @@ -111,8 +111,8 @@ describe("resolvePreferredNodePath", () => { it("skips system node when it is too old", async () => { mockNodePathPresent(darwinNode); - // Node 22.11.x is below minimum 22.12.0 - const execFile = vi.fn().mockResolvedValue({ stdout: "22.11.0\n", stderr: "" }); + // Node 22.15.x is below minimum 22.16.0 + const execFile = vi.fn().mockResolvedValue({ stdout: "22.15.0\n", stderr: "" }); const result = await resolvePreferredNodePath({ env: {}, @@ -168,7 +168,7 @@ describe("resolveStableNodePath", () => { it("resolves versioned node@22 formula to opt symlink", async () => { mockNodePathPresent("/opt/homebrew/opt/node@22/bin/node"); - const result = await resolveStableNodePath("/opt/homebrew/Cellar/node@22/22.12.0/bin/node"); + const result = await resolveStableNodePath("/opt/homebrew/Cellar/node@22/22.16.0/bin/node"); expect(result).toBe("/opt/homebrew/opt/node@22/bin/node"); }); @@ -218,8 +218,8 @@ describe("resolveSystemNodeInfo", () => { it("returns supported info when version is new enough", async () => { mockNodePathPresent(darwinNode); - // Node 22.12.0+ is the minimum required version - const execFile = vi.fn().mockResolvedValue({ stdout: "22.12.0\n", stderr: "" }); + // Node 22.16.0+ is the minimum required version + const execFile = vi.fn().mockResolvedValue({ stdout: "22.16.0\n", stderr: "" }); const result = await resolveSystemNodeInfo({ env: {}, @@ -229,7 +229,7 @@ describe("resolveSystemNodeInfo", () => { expect(result).toEqual({ path: darwinNode, - version: "22.12.0", + version: "22.16.0", supported: true, }); }); diff --git a/src/infra/runtime-guard.test.ts b/src/infra/runtime-guard.test.ts index b9ffb2af52c..410fe5d4a2d 100644 --- a/src/infra/runtime-guard.test.ts +++ b/src/infra/runtime-guard.test.ts @@ -16,16 +16,16 @@ describe("runtime-guard", () => { }); it("compares versions correctly", () => { - expect(isAtLeast({ major: 22, minor: 12, patch: 0 }, { major: 22, minor: 12, patch: 0 })).toBe( + expect(isAtLeast({ major: 22, minor: 16, patch: 0 }, { major: 22, minor: 16, patch: 0 })).toBe( true, ); - expect(isAtLeast({ major: 22, minor: 13, patch: 0 }, { major: 22, minor: 12, patch: 0 })).toBe( + expect(isAtLeast({ major: 22, minor: 17, patch: 0 }, { major: 22, minor: 16, patch: 0 })).toBe( true, ); - expect(isAtLeast({ major: 22, minor: 11, patch: 0 }, { major: 22, minor: 12, patch: 0 })).toBe( + expect(isAtLeast({ major: 22, minor: 15, patch: 0 }, { major: 22, minor: 16, patch: 0 })).toBe( false, ); - expect(isAtLeast({ major: 21, minor: 9, patch: 0 }, { major: 22, minor: 12, patch: 0 })).toBe( + expect(isAtLeast({ major: 21, minor: 9, patch: 0 }, { major: 22, minor: 16, patch: 0 })).toBe( false, ); }); @@ -33,11 +33,11 @@ describe("runtime-guard", () => { it("validates runtime thresholds", () => { const nodeOk: RuntimeDetails = { kind: "node", - version: "22.12.0", + version: "22.16.0", execPath: "/usr/bin/node", pathEnv: "/usr/bin", }; - const nodeOld: RuntimeDetails = { ...nodeOk, version: "22.11.0" }; + const nodeOld: RuntimeDetails = { ...nodeOk, version: "22.15.0" }; const nodeTooOld: RuntimeDetails = { ...nodeOk, version: "21.9.0" }; const unknown: RuntimeDetails = { kind: "unknown", @@ -78,7 +78,7 @@ describe("runtime-guard", () => { const details: RuntimeDetails = { ...detectRuntime(), kind: "node", - version: "22.12.0", + version: "22.16.0", execPath: "/usr/bin/node", }; expect(() => assertSupportedRuntime(runtime, details)).not.toThrow(); diff --git a/src/infra/runtime-guard.ts b/src/infra/runtime-guard.ts index 1a56e48abbc..51c187a9e31 100644 --- a/src/infra/runtime-guard.ts +++ b/src/infra/runtime-guard.ts @@ -9,7 +9,7 @@ type Semver = { patch: number; }; -const MIN_NODE: Semver = { major: 22, minor: 12, patch: 0 }; +const MIN_NODE: Semver = { major: 22, minor: 16, patch: 0 }; export type RuntimeDetails = { kind: RuntimeKind; @@ -88,7 +88,7 @@ export function assertSupportedRuntime( runtime.error( [ - "openclaw requires Node >=22.12.0.", + "openclaw requires Node >=22.16.0.", `Detected: ${runtimeLabel} (exec: ${execLabel}).`, `PATH searched: ${details.pathEnv}`, "Install Node: https://nodejs.org/en/download", diff --git a/src/memory/embeddings.ts b/src/memory/embeddings.ts index 20df6028a60..3e38ef7f210 100644 --- a/src/memory/embeddings.ts +++ b/src/memory/embeddings.ts @@ -310,7 +310,7 @@ function formatLocalSetupError(err: unknown): string { : undefined, missing && detail ? `Detail: ${detail}` : null, "To enable local embeddings:", - "1) Use Node 24 (recommended for installs/updates; Node 22.12+ remains supported)", + "1) Use Node 24 (recommended for installs/updates; Node 22 LTS, currently 22.16+, remains supported)", missing ? "2) Reinstall OpenClaw (this should install node-llama-cpp): npm i -g openclaw@latest" : null,