94 lines
4.3 KiB
Markdown
94 lines
4.3 KiB
Markdown
# Node.js Runtime Fix
|
|
|
|
**Date**: 2026-02
|
|
**Scope**: Worker runtime loading, environment setup, action execution
|
|
|
|
## Problem
|
|
|
|
Node.js actions from installed packs (e.g., `nodejs_example`) were stuck in "In Progress" status and never completing. Three root causes were identified:
|
|
|
|
### 1. Runtime Name Mismatch (Blocking)
|
|
|
|
The `ATTUNE_WORKER_RUNTIMES` env var for the node worker is `shell,node`, but the database runtime name is "Node.js" which lowercases to `"node.js"`. The worker's filter used exact string matching (`filter.contains(&rt_name)`), so `"node.js"` was never found in `["shell", "node"]`. **The Node.js ProcessRuntime was never registered**, meaning no worker could handle Node.js executions.
|
|
|
|
### 2. Broken Environment Setup
|
|
|
|
The Node.js `execution_config` in `packs/core/runtimes/nodejs.yaml` had:
|
|
- `create_command: ["npm", "init", "-y"]` — ran in the pack directory (read-only in Docker), didn't create anything at `{env_dir}`
|
|
- `install_command: ["npm", "install", "--prefix", "{pack_dir}"]` — tried to write `node_modules` into the read-only pack directory
|
|
|
|
### 3. Missing NODE_PATH
|
|
|
|
Even with correct installation, Node.js couldn't find modules installed at `{env_dir}/node_modules` because Node resolves modules relative to the script location, not the environment directory. No mechanism existed to set `NODE_PATH` during execution.
|
|
|
|
## Solution
|
|
|
|
### Runtime Name Normalization
|
|
|
|
Added `normalize_runtime_name()` and `runtime_in_filter()` to `crates/common/src/runtime_detection.rs`. These functions map common aliases to canonical names:
|
|
- `node` / `nodejs` / `node.js` → `node`
|
|
- `python` / `python3` → `python`
|
|
- `shell` / `bash` / `sh` → `shell`
|
|
- `native` / `builtin` / `standalone` → `native`
|
|
|
|
Updated `crates/worker/src/service.rs` and `crates/worker/src/env_setup.rs` to use `runtime_in_filter()` instead of exact string matching.
|
|
|
|
### RuntimeExecutionConfig.env_vars
|
|
|
|
Added an `env_vars: HashMap<String, String>` field to `RuntimeExecutionConfig` in `crates/common/src/models.rs`. Values support the same template variables as other fields (`{env_dir}`, `{pack_dir}`, `{interpreter}`, `{manifest_path}`).
|
|
|
|
In `ProcessRuntime::execute` (`crates/worker/src/runtime/process.rs`), runtime env_vars are resolved and injected into the action's environment before building the command.
|
|
|
|
### Fixed Node.js Runtime Config
|
|
|
|
Updated `packs/core/runtimes/nodejs.yaml` and `scripts/seed_runtimes.sql`:
|
|
|
|
```yaml
|
|
execution_config:
|
|
interpreter:
|
|
binary: node
|
|
args: []
|
|
file_extension: ".js"
|
|
environment:
|
|
env_type: node_modules
|
|
dir_name: node_modules
|
|
create_command:
|
|
- sh
|
|
- "-c"
|
|
- "mkdir -p {env_dir} && cp {manifest_path} {env_dir}/ 2>/dev/null || true"
|
|
interpreter_path: null
|
|
dependencies:
|
|
manifest_file: package.json
|
|
install_command:
|
|
- npm
|
|
- install
|
|
- "--prefix"
|
|
- "{env_dir}"
|
|
env_vars:
|
|
NODE_PATH: "{env_dir}/node_modules"
|
|
```
|
|
|
|
## Files Changed
|
|
|
|
| File | Change |
|
|
|------|--------|
|
|
| `crates/common/src/models.rs` | Added `env_vars` field to `RuntimeExecutionConfig` |
|
|
| `crates/common/src/runtime_detection.rs` | Added `normalize_runtime_name()`, `runtime_matches_filter()`, `runtime_in_filter()` with tests |
|
|
| `crates/worker/src/service.rs` | Use `runtime_in_filter()` for ATTUNE_WORKER_RUNTIMES matching |
|
|
| `crates/worker/src/env_setup.rs` | Use `runtime_in_filter()` for runtime filter matching in env setup |
|
|
| `crates/worker/src/runtime/process.rs` | Inject `env_vars` into action environment during execution |
|
|
| `crates/worker/src/runtime/local.rs` | Added `env_vars` field to fallback config |
|
|
| `packs/core/runtimes/nodejs.yaml` | Fixed `create_command`, `install_command`, added `env_vars` |
|
|
| `scripts/seed_runtimes.sql` | Fixed Node.js execution_config to match YAML |
|
|
| `crates/worker/tests/*.rs` | Added `env_vars` field to test configs |
|
|
| `AGENTS.md` | Documented runtime name normalization, env_vars, and env setup requirements |
|
|
|
|
## Testing
|
|
|
|
- All 424 unit tests pass
|
|
- Zero compiler warnings
|
|
- New tests for `normalize_runtime_name`, `runtime_matches_filter`, `runtime_in_filter`
|
|
|
|
## Deployment Notes
|
|
|
|
After deploying, the Node.js runtime config in the database needs to be updated. This happens automatically when packs are re-registered (the pack loader reads the updated YAML). Alternatively, run the updated `seed_runtimes.sql` script. |