diff --git a/ct/termix.sh b/ct/termix.sh index cac5acfa1..fac375992 100644 --- a/ct/termix.sh +++ b/ct/termix.sh @@ -155,6 +155,8 @@ EOF /opt/termix/nginx/client_body msg_ok "Recreated Directories" + NODE_VERSION="24" setup_nodejs + msg_info "Building Frontend" cd /opt/termix export COREPACK_ENABLE_DOWNLOAD_PROMPT=0 diff --git a/misc/error_handler.func b/misc/error_handler.func index dd816dc22..50e8dac42 100644 --- a/misc/error_handler.func +++ b/misc/error_handler.func @@ -313,6 +313,51 @@ error_handler() { echo -e "${TAB}-----------------------------------\n" fi + # Detect probable Node.js heap OOM and print actionable guidance. + # This avoids generic SIGABRT/SIGKILL confusion for frontend build failures. + local node_oom_detected="false" + local node_build_context="false" + if [[ "$command" =~ (npm|pnpm|yarn|node|vite|turbo) ]]; then + node_build_context="true" + fi + if [[ "$exit_code" == "243" ]]; then + node_oom_detected="true" + elif [[ -n "$active_log" && -s "$active_log" ]]; then + if tail -n 200 "$active_log" 2>/dev/null | grep -Eqi 'Reached heap limit|JavaScript heap out of memory|Allocation failed - JavaScript heap out of memory|FATAL ERROR: Reached heap limit'; then + node_oom_detected="true" + fi + fi + + if [[ "$node_oom_detected" == "true" ]] || { [[ "$node_build_context" == "true" ]] && [[ "$exit_code" =~ ^(134|137)$ ]]; }; then + local heap_hint_mb="" + + # If explicitly configured, prefer the current value for troubleshooting output. + if [[ -n "${NODE_OPTIONS:-}" ]] && [[ "${NODE_OPTIONS}" =~ max-old-space-size=([0-9]+) ]]; then + heap_hint_mb="${BASH_REMATCH[1]}" + elif [[ -n "${var_ram:-}" ]] && [[ "${var_ram}" =~ ^[0-9]+$ ]]; then + heap_hint_mb=$((var_ram * 75 / 100)) + else + local mem_kb="" + mem_kb=$(awk '/^MemTotal:/ {print $2; exit}' /proc/meminfo 2>/dev/null || echo "") + if [[ "$mem_kb" =~ ^[0-9]+$ ]]; then + local mem_mb=$((mem_kb / 1024)) + heap_hint_mb=$((mem_mb * 75 / 100)) + fi + fi + + if [[ -z "$heap_hint_mb" ]] || ((heap_hint_mb < 1024)); then + heap_hint_mb=1024 + elif ((heap_hint_mb > 12288)); then + heap_hint_mb=12288 + fi + + if declare -f msg_warn >/dev/null 2>&1; then + msg_warn "Possible Node.js heap OOM. Try: export NODE_OPTIONS=\"--max-old-space-size=${heap_hint_mb}\" and rerun the build." + else + echo -e "${YW}Possible Node.js heap OOM. Try: export NODE_OPTIONS=\"--max-old-space-size=${heap_hint_mb}\" and rerun the build.${CL}" + fi + fi + # Detect context: Container (INSTALL_LOG set + inside container /root) vs Host if [[ -n "${INSTALL_LOG:-}" && -f "${INSTALL_LOG:-}" && -d /root ]]; then # CONTAINER CONTEXT: Copy log and create flag file for host diff --git a/misc/tools.func b/misc/tools.func index 751210ed9..81621a8f3 100644 --- a/misc/tools.func +++ b/misc/tools.func @@ -6423,7 +6423,37 @@ function setup_nodejs() { msg_ok "Setup Node.js $NODE_VERSION" fi - export NODE_OPTIONS="--max-old-space-size=4096" + # Set a safe default heap limit for Node.js builds if not explicitly provided. + # Priority: + # 1) NODE_OPTIONS (caller/user override) + # 2) NODE_MAX_OLD_SPACE_SIZE (explicit MB override) + # 3) var_ram (LXC memory setting, MB) + # 4) /proc/meminfo (runtime memory detection) + # Auto value is clamped to 1024..12288 MB. + if [[ -z "${NODE_OPTIONS:-}" ]]; then + local node_heap_mb="" + + if [[ -n "${NODE_MAX_OLD_SPACE_SIZE:-}" ]] && [[ "${NODE_MAX_OLD_SPACE_SIZE}" =~ ^[0-9]+$ ]]; then + node_heap_mb="${NODE_MAX_OLD_SPACE_SIZE}" + elif [[ -n "${var_ram:-}" ]] && [[ "${var_ram}" =~ ^[0-9]+$ ]]; then + node_heap_mb=$((var_ram * 75 / 100)) + else + local total_mem_kb="" + total_mem_kb=$(awk '/^MemTotal:/ {print $2; exit}' /proc/meminfo 2>/dev/null || echo "") + if [[ "$total_mem_kb" =~ ^[0-9]+$ ]]; then + local total_mem_mb=$((total_mem_kb / 1024)) + node_heap_mb=$((total_mem_mb * 75 / 100)) + fi + fi + + if [[ -z "$node_heap_mb" ]] || ((node_heap_mb < 1024)); then + node_heap_mb=1024 + elif ((node_heap_mb > 12288)); then + node_heap_mb=12288 + fi + + export NODE_OPTIONS="--max-old-space-size=${node_heap_mb}" + fi # Ensure valid working directory for npm (avoids uv_cwd error) if [[ ! -d /opt ]]; then