From 08f992699022581bf63cc31045a679ff4678231d Mon Sep 17 00:00:00 2001 From: Julie Yaunches Date: Mon, 8 Jun 2026 13:26:42 -0400 Subject: [PATCH 1/2] fix(sandbox): stage patch-openclaw-slack-deny-feedback.mts in build context MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PR #4933 added `scripts/patch-openclaw-slack-deny-feedback.mts` and a matching `COPY` in the Dockerfile, but did not register the new file in `stageOptimizedSandboxBuildContext`. The optimized staging path therefore omits it, and `docker build` fails at step 23 with: COPY failed: file not found in build context: stat scripts/patch-openclaw-slack-deny-feedback.mts: file does not exist This took out 48 of 67 jobs in nightly run 27154074940 — every E2E job that performs onboard/install via the sandbox image was killed before any test logic ran. Fix: stage the new patch alongside its two siblings, and extend the build-context test to assert it lands in the staged context. --- src/lib/sandbox/build-context.ts | 4 ++++ test/sandbox-build-context.test.ts | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/src/lib/sandbox/build-context.ts b/src/lib/sandbox/build-context.ts index 16f6f99ba03..4e5ece1b4d1 100644 --- a/src/lib/sandbox/build-context.ts +++ b/src/lib/sandbox/build-context.ts @@ -160,6 +160,10 @@ function stageOptimizedSandboxBuildContext( path.join(rootDir, "scripts", "patch-openclaw-chat-send.js"), path.join(stagedScriptsDir, "patch-openclaw-chat-send.js"), ); + fs.copyFileSync( + path.join(rootDir, "scripts", "patch-openclaw-slack-deny-feedback.mts"), + path.join(stagedScriptsDir, "patch-openclaw-slack-deny-feedback.mts"), + ); return { buildCtx, stagedDockerfile }; } diff --git a/test/sandbox-build-context.test.ts b/test/sandbox-build-context.test.ts index af8e8b3a0b2..47a8c14df35 100644 --- a/test/sandbox-build-context.test.ts +++ b/test/sandbox-build-context.test.ts @@ -80,6 +80,7 @@ describe("sandbox build context staging", () => { writeFixture(path.join("scripts", "seed-wechat-accounts.py")); writeFixture(path.join("scripts", "patch-openclaw-tool-catalog.js")); writeFixture(path.join("scripts", "patch-openclaw-chat-send.js")); + writeFixture(path.join("scripts", "patch-openclaw-slack-deny-feedback.mts")); } function expectStagedNemoclawModes(buildCtx: string) { @@ -265,6 +266,9 @@ describe("sandbox build context staging", () => { expect(fs.existsSync(path.join(buildCtx, "scripts", "patch-openclaw-chat-send.js"))).toBe( true, ); + expect( + fs.existsSync(path.join(buildCtx, "scripts", "patch-openclaw-slack-deny-feedback.mts")), + ).toBe(true); expect(fs.existsSync(path.join(buildCtx, "scripts", "lib", "sandbox-init.sh"))).toBe(true); expect(fs.existsSync(path.join(buildCtx, "scripts", "setup.sh"))).toBe(false); } finally { From 7fca86f78bc42304bceccb561174ab05f57b5b37 Mon Sep 17 00:00:00 2001 From: Carlos Villela Date: Mon, 8 Jun 2026 10:40:04 -0700 Subject: [PATCH 2/2] test(sandbox): guard Dockerfile script staging Signed-off-by: Carlos Villela --- test/sandbox-build-context.test.ts | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/test/sandbox-build-context.test.ts b/test/sandbox-build-context.test.ts index 47a8c14df35..f7450a812d1 100644 --- a/test/sandbox-build-context.test.ts +++ b/test/sandbox-build-context.test.ts @@ -83,6 +83,18 @@ describe("sandbox build context staging", () => { writeFixture(path.join("scripts", "patch-openclaw-slack-deny-feedback.mts")); } + function expectDockerfileScriptCopiesExist(buildCtx: string, stagedDockerfile: string) { + const dockerfile = fs.readFileSync(stagedDockerfile, "utf8"); + const copiedScripts = [...dockerfile.matchAll(/^COPY\s+scripts\/(\S+)/gm)].map( + ([, relativePath]) => relativePath, + ); + expect(copiedScripts).not.toHaveLength(0); + + for (const relativePath of copiedScripts) { + expect(fs.existsSync(path.join(buildCtx, "scripts", relativePath))).toBe(true); + } + } + function expectStagedNemoclawModes(buildCtx: string) { const stagedNemoclaw = path.join(buildCtx, "nemoclaw"); const stagedSrc = path.join(stagedNemoclaw, "src"); @@ -212,7 +224,8 @@ describe("sandbox build context staging", () => { const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "nemoclaw-build-context-opt-")); try { - const { buildCtx } = stageOptimizedSandboxBuildContext(repoRoot, tmpDir); + const { buildCtx, stagedDockerfile } = stageOptimizedSandboxBuildContext(repoRoot, tmpDir); + expectDockerfileScriptCopiesExist(buildCtx, stagedDockerfile); expect(fs.existsSync(path.join(buildCtx, "nemoclaw-blueprint", ".venv"))).toBe(false); expect(fs.existsSync(path.join(buildCtx, "nemoclaw-blueprint", "blueprint.yaml"))).toBe(true); expect(