Skip to content

Commit 40aef0d

Browse files
quickbeardclaude
andcommitted
fix(sandbox): run the guest on Node 24 and probe /path in the e2es
The guest ran the server bundle on Node 22, whose node:sqlite lacks StatementSync.setReturnArrays — the bundle is built against Electron's Node 24, so every DB-touching route died with UnknownError while /global/health kept passing, which is exactly what the health-only e2e checked. Track the Electron Node major (24) in the image, and make both e2e drivers also probe /path, the cheapest route that boots the instance store. Found via the first in-app run: the sandbox reached Ready but the project picker listed nothing; reproduced in the guest rootfs under Docker, where the server log carried the TypeError. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
1 parent ccd6641 commit 40aef0d

3 files changed

Lines changed: 31 additions & 3 deletions

File tree

‎packages/codev-sandbox/image/Dockerfile‎

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,11 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
1313
build-essential pkg-config \
1414
&& rm -rf /var/lib/apt/lists/*
1515
ARG TARGETARCH
16-
ARG NODE_VERSION=v22.15.0
16+
# Track the Node major Electron embeds (Electron 42 = Node 24): the guest runs
17+
# the same server bundle as the desktop sidecar, and the bundle uses node:sqlite
18+
# APIs (StatementSync.setReturnArrays) that Node 22 does not have — under 22
19+
# every DB-touching route fails while /global/health still passes.
20+
ARG NODE_VERSION=v24.19.0
1721
RUN set -eux; \
1822
case "$TARGETARCH" in amd64) NODE_ARCH=x64 ;; arm64) NODE_ARCH=arm64 ;; *) echo "unsupported arch: $TARGETARCH" >&2; exit 1 ;; esac; \
1923
curl -fsSL "https://nodejs.org/dist/${NODE_VERSION}/node-${NODE_VERSION}-linux-${NODE_ARCH}.tar.xz" \

‎packages/codev-sandbox/script/e2e-vz.ts‎

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,18 @@ console.log(`server: ${sandbox.url} (user ${sandbox.username})`)
5858
const healthy = await checkSandboxHealth(sandbox.url, { username: sandbox.username ?? "", password: sandbox.password })
5959
console.log(`health: ${healthy ? "OK" : "FAILED"}`)
6060

61+
// /global/health never touches the instance store; /path boots it, so this is
62+
// the probe that catches a guest runtime the bundle cannot actually run on
63+
// (e.g. a node:sqlite too old for the bundle's prepared statements).
64+
const pathsOk = await fetch(`${sandbox.url}/path`, {
65+
headers: {
66+
authorization: `Basic ${Buffer.from(`${sandbox.username ?? ""}:${sandbox.password}`).toString("base64")}`,
67+
},
68+
})
69+
.then((response) => response.ok)
70+
.catch(() => false)
71+
console.log(`path api: ${pathsOk ? "OK" : "FAILED"}`)
72+
6173
if (hold) {
6274
console.log("holding the VM up; Ctrl-C to stop")
6375
await new Promise(() => {})
@@ -69,7 +81,7 @@ await Promise.race([exited, new Promise((resolve) => setTimeout(resolve, 10_000)
6981
await provider.destroy(config)
7082
server.stop(true)
7183
await rm(work, { recursive: true, force: true })
72-
if (!healthy) process.exit(1)
84+
if (!healthy || !pathsOk) process.exit(1)
7385
console.log("e2e OK")
7486
process.exit(0)
7587

‎packages/codev-sandbox/script/e2e-wsl.ts‎

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,18 @@ console.log(`server: ${sandbox.url} (user ${sandbox.username})`)
7474
const healthy = await checkSandboxHealth(sandbox.url, { username: sandbox.username ?? "", password: sandbox.password })
7575
console.log(`health: ${healthy ? "OK" : "FAILED"}`)
7676

77+
// /global/health never touches the instance store; /path boots it, so this is
78+
// the probe that catches a guest runtime the bundle cannot actually run on
79+
// (e.g. a node:sqlite too old for the bundle's prepared statements).
80+
const pathsOk = await fetch(`${sandbox.url}/path`, {
81+
headers: {
82+
authorization: `Basic ${Buffer.from(`${sandbox.username ?? ""}:${sandbox.password}`).toString("base64")}`,
83+
},
84+
})
85+
.then((response) => response.ok)
86+
.catch(() => false)
87+
console.log(`path api: ${pathsOk ? "OK" : "FAILED"}`)
88+
7789
if (hold) {
7890
console.log("holding the distribution up; Ctrl-C to stop")
7991
await new Promise(() => {})
@@ -85,7 +97,7 @@ await Promise.race([exited, new Promise((resolve) => setTimeout(resolve, 10_000)
8597
if (keep) console.log(`keeping the distribution; remove it with: wsl --unregister codev-${config.name}`)
8698
if (!keep) await provider.destroy(config)
8799
await cleanup()
88-
if (!healthy) process.exit(1)
100+
if (!healthy || !pathsOk) process.exit(1)
89101
console.log("e2e OK")
90102
process.exit(0)
91103

0 commit comments

Comments
 (0)