From 4c6c9660c3ed6bc1af3c4c9ead0b9090052f1707 Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Tue, 7 Jul 2026 00:07:05 +0100 Subject: [PATCH] fix(install): raise postinstall dist scan budget so npm upgrades cannot trip the shared cap (#101206) The single InstalledDistScanBudget is consumed across all three prune walks (legacy-deps prepass, dist file listing, empty-dir sweep). During an npm upgrade the dist dir transiently holds old+new content-hashed files, so a real upgrade scan totals ~24k entries against the 25k cap; one more release of dist growth would make 'npm install -g openclaw' throw InstalledDistScanLimitError for every upgrading user. Raise the cap to 100k for real headroom while keeping the unbounded-scan guard, and ratchet the cap in the test so it cannot be lowered back. --- scripts/postinstall-bundled-plugins.mjs | 7 ++++++- test/scripts/postinstall-bundled-plugins.test.ts | 5 ++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/scripts/postinstall-bundled-plugins.mjs b/scripts/postinstall-bundled-plugins.mjs index 39dc35c42b1..7f72ee8b3fa 100644 --- a/scripts/postinstall-bundled-plugins.mjs +++ b/scripts/postinstall-bundled-plugins.mjs @@ -30,7 +30,12 @@ const DEFAULT_PACKAGE_ROOT = join(scriptDir, ".."); const DISABLE_POSTINSTALL_ENV = "OPENCLAW_DISABLE_BUNDLED_PLUGIN_POSTINSTALL"; const DISABLE_PLUGIN_REGISTRY_MIGRATION_ENV = "OPENCLAW_DISABLE_PLUGIN_REGISTRY_MIGRATION"; const DIST_INVENTORY_PATH = "dist/postinstall-inventory.json"; -export const MAX_INSTALLED_DIST_SCAN_ENTRIES = 25_000; +// One budget covers all three prune walks (legacy-deps prepass, file listing, +// empty-dir sweep). npm upgrades transiently hold old+new content-hashed dist +// files, so a real upgrade scan totals ~24k entries today (2026.6.x); keep ~4x +// headroom so dist growth cannot fail `npm install -g` while still refusing +// pathological/unbounded trees. +export const MAX_INSTALLED_DIST_SCAN_ENTRIES = 100_000; const LEGACY_PLUGIN_RUNTIME_DEPS_DIR = "plugin-runtime-deps"; const BAILEYS_MEDIA_FILE = join("node_modules", "baileys", "lib", "Utils", "messages-media.js"); const BAILEYS_MEDIA_HOTFIX_NEEDLE = [ diff --git a/test/scripts/postinstall-bundled-plugins.test.ts b/test/scripts/postinstall-bundled-plugins.test.ts index 40727bb72a2..4f4f6e55866 100644 --- a/test/scripts/postinstall-bundled-plugins.test.ts +++ b/test/scripts/postinstall-bundled-plugins.test.ts @@ -991,7 +991,10 @@ describe("bundled plugin postinstall", () => { ).toThrow( "installed dist scan exceeded 1 filesystem entries; refusing to scan unbounded package contents", ); - expect(MAX_INSTALLED_DIST_SCAN_ENTRIES).toBeGreaterThan(1); + // One budget spans all three prune walks, and npm upgrades scan old+new + // content-hashed dist files (~24k entries as of 2026.6.x). A cap without + // several-x headroom fails `npm install -g openclaw` for upgrading users. + expect(MAX_INSTALLED_DIST_SCAN_ENTRIES).toBeGreaterThanOrEqual(100_000); }); it("uses one packaged dist scan budget across listing and pruning phases", () => {