From c08a0be3dd2700ec37c7aff57cef4bf71ef0aed0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Burak=20Emre=20Kabakc=C4=B1?= Date: Mon, 27 Apr 2026 23:59:25 +0100 Subject: [PATCH] =?UTF-8?q?revert(execute):=20drop=20runtime=20swap=20in?= =?UTF-8?q?=20#430=20=E2=80=94=20keep=20prod=20on=20bun?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PR #430 switched docker/app/start.sh from 'exec bun src/server.ts' to 'exec node --import tsx src/server.ts' so isolated-vm could load. End-to-end smoke in the live image confirmed the runtime swap itself worked, but the resulting prod image crashloops on boot: SyntaxError: The requested module '@lobu/core' does not provide an export named 'createBuiltinSecretRef' at packages/owletto-backend/src/lobu/stores/postgres-secret-store.ts:13 The export exists in @lobu/core/dist/secret-refs.js. Node's cjs-module-lexer detects it when the file is the sole entry, but fails to detect it when reached via the full server.ts boot chain. Bun has its own CJS↔ESM interop and didn't hit this. Fixing properly requires shipping @lobu/core as dual ESM+CJS instead of CJS-only behind an 'import' condition. Reverting unblocks the partial deploy. Old pods are still serving traffic (CrashLoopBackOff prevented rollover). The execute tool returns to its pre-#430 state — same RuntimeUnavailable behavior that's been in prod since #427 hardened the load failure. No user-facing regression beyond what we already had this morning. Tracked: convert @lobu/core (and other workspace packages with the same shape) to dual ESM+CJS so the runtime swap can land cleanly. --- docker/app/start.sh | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/docker/app/start.sh b/docker/app/start.sh index 5062b5b4b..533612369 100644 --- a/docker/app/start.sh +++ b/docker/app/start.sh @@ -3,7 +3,7 @@ set -e MODE="${1:-server}" -echo "Starting Owletto backend (Node + tsx)" +echo "Starting Owletto backend (Bun)" echo "================================" echo "Environment:" @@ -41,16 +41,15 @@ else run_migrations fi -# Run under Node so V8 native addons (isolated-vm) load. -# Bun uses JavaScriptCore and cannot link the V8 ABI surface that -# isolated-vm requires; the execute MCP tool silently degrades to -# RuntimeUnavailable under bun. tsx provides the TS loader so the -# source layout stays uncompiled. -# -# Keep cwd=/app — gateway services and embedded agent routes resolve -# bundled config (`config/providers.json`) relative to process.cwd(). -# Use the absolute tsx loader path so the resolution doesn't depend -# on cwd or PATH. -exec node \ - --import "file:///app/packages/owletto-backend/node_modules/tsx/dist/loader.mjs" \ - /app/packages/owletto-backend/src/server.ts +# NOTE: prod runs under Bun. The execute MCP tool requires V8 +# (isolated-vm), which Bun's JSC ABI shim cannot load. PR #430 attempted +# to switch the runtime to `node --import tsx`, but exposed a CJS/ESM +# interop gap: Node's cjs-module-lexer doesn't detect new named exports +# of @lobu/core's CJS dist when the static import follows certain +# reachability paths (e.g. the full server.ts boot chain hits +# `SyntaxError: ... does not provide an export named 'createBuiltinSecretRef'`, +# even though a same-imports test entry resolves fine). Reverted on the +# understanding that fixing properly means making @lobu/core (and other +# workspace packages) ship dual ESM+CJS output instead of CJS-only with +# an `import` condition. Tracked separately. +exec bun /app/packages/owletto-backend/src/server.ts