{"record":{"id":"39ee3ac95d95d989","repo":"calesthio/OpenMontage","slug":"error-node-js-is-required-install-it-from-https","errorCode":null,"errorMessage":"Error: Node.js is required. Install it from https://nodejs.org/","messagePattern":"Error: Node\\.js is required\\. Install it from https://nodejs\\.org/","errorType":"console","errorClass":"SystemExit","httpStatus":null,"severity":"error","filePath":"render_demo.py","lineNumber":51,"sourceCode":"\n\ndef discover_demos() -> dict[str, Path]:\n    if not PROPS_DIR.exists():\n        return {}\n    return {path.stem: path for path in sorted(PROPS_DIR.glob(\"*.json\"))}\n\n\ndef find_command(*names: str) -> str | None:\n    for name in names:\n        resolved = shutil.which(name)\n        if resolved:\n            return resolved\n    return None\n\n\ndef ensure_demo_environment() -> str:\n    if not find_command(\"node\", \"node.exe\"):\n        raise SystemExit(\"Error: Node.js is required. Install it from https://nodejs.org/\")\n\n    npm_cmd = find_command(\"npm.cmd\", \"npm\", \"npm.exe\")\n    if not npm_cmd:\n        raise SystemExit(\"Error: npm is required but was not found on PATH.\")\n\n    npx_cmd = find_command(\"npx.cmd\", \"npx\", \"npx.exe\")\n    if not npx_cmd:\n        raise SystemExit(\"Error: npx is required but was not found on PATH.\")\n\n    if not (COMPOSER_DIR / \"node_modules\").exists():\n        print(\"Installing Remotion dependencies...\")\n        subprocess.run([npm_cmd, \"install\"], cwd=COMPOSER_DIR, check=True)\n\n    return npx_cmd\n\n\ndef validate_props_file(path: Path) -> None:\n    with path.open(\"r\", encoding=\"utf-8\") as handle:","sourceCodeStart":33,"sourceCodeEnd":69,"githubUrl":"https://github.com/calesthio/OpenMontage/blob/95e1c3d0ab93482159818560f6a8c8e866b9139f/render_demo.py#L33-L69","documentation":"Raised by render_demo.py's ensure_demo_environment() as SystemExit when neither 'node' nor 'node.exe' is found on PATH via shutil.which. The demo renderer drives Remotion through npx, which requires a Node.js runtime; this is a preflight check that fails before any npm install or render subprocess is spawned, giving an actionable message instead of a cryptic spawn error.","triggerScenarios":"Running render_demo.py on a machine without Node.js installed; Node installed via a version manager (nvm/fnm) but the shell session hasn't activated it; PATH mangled inside an IDE/CI launcher so the node binary directory isn't included.","commonSituations":"Fresh machine or container without Node; CI image missing the Node setup step; nvm installed but the current shell didn't source it; Windows where node.exe is on PATH but named differently or missing entirely.","solutions":["Install Node.js (LTS) from https://nodejs.org/ or via your package manager, then reopen the terminal so PATH updates.","If you use nvm/fnm/volta, run its activation command (e.g. nvm use --lts) in the same shell before rerunning.","In CI, add a Node setup step (e.g. actions/setup-node) before invoking render_demo.py."],"exampleFix":"# shell — before\npython render_demo.py  # SystemExit: Node.js is required\n\n# shell — after\n# macOS/Linux\nbrew install node@lts || nvm install --lts && nvm use --lts\npython render_demo.py","handlingStrategy":"validation","validationCode":"import shutil\n\nif not shutil.which(\"node\"):\n    raise SystemExit(\"Node.js is required. Install it from https://nodejs.org/ and reopen your terminal.\")","typeGuard":"import shutil\n\ndef node_available() -> bool:\n    return shutil.which(\"node\") is not None or shutil.which(\"node.exe\") is not None","tryCatchPattern":"try:\n    npx = ensure_demo_environment()\nexcept SystemExit as e:\n    print(f\"Environment not ready: {e}\")\n    return 1","preventionTips":["Install a Node LTS and verify with `node --version` in the same shell you render from.","Activate nvm/fnm/volta in each new shell or CI step.","Add a Node setup step to CI before any render job."],"tags":["environment","nodejs","prerequisites","rendering"],"backgroundTag":null,"analyzedSha":"95e1c3d0ab93482159818560f6a8c8e866b9139f","analyzedAt":"2026-08-15T06:31:20.014Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}