Frappe-Manager icon indicating copy to clipboard operation
Frappe-Manager copied to clipboard

FileNotFoundError: [Errno 2] No such file or directory: 'node'

Open victorarocha opened this issue 3 months ago • 3 comments

Describe the bug Trying to save a website theme, throws this error:

Traceback (most recent call last):
  File "apps/frappe/frappe/app.py", line 121, in application
    response = frappe.api.handle(request)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "apps/frappe/frappe/api/__init__.py", line 61, in handle
    data = endpoint(**arguments)
           ^^^^^^^^^^^^^^^^^^^^^
  File "apps/frappe/frappe/api/v1.py", line 36, in handle_rpc_call
    return frappe.handler.handle()
           ^^^^^^^^^^^^^^^^^^^^^^^
  File "apps/frappe/frappe/handler.py", line 52, in handle
    data = execute_cmd(cmd)
           ^^^^^^^^^^^^^^^^
  File "apps/frappe/frappe/handler.py", line 85, in execute_cmd
    return frappe.call(method, **frappe.form_dict)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "apps/frappe/frappe/__init__.py", line 1127, in call
    return fn(*args, **newargs)
           ^^^^^^^^^^^^^^^^^^^^
  File "apps/frappe/frappe/utils/typing_validations.py", line 36, in wrapper
    return func(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^
  File "apps/frappe/frappe/desk/form/save.py", line 43, in savedocs
    doc.save()
  File "apps/frappe/frappe/model/document.py", line 485, in save
    return self._save(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "apps/frappe/frappe/model/document.py", line 521, in _save
    self.run_before_save_methods()
  File "apps/frappe/frappe/model/document.py", line 1284, in run_before_save_methods
    self.run_method("validate")
  File "apps/frappe/frappe/model/document.py", line 1133, in run_method
    out = Document.hook(fn)(self, *args, **kwargs)
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "apps/frappe/frappe/model/document.py", line 1530, in composer
    return composed(self, method, *args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "apps/frappe/frappe/model/document.py", line 1508, in runner
    add_to_return_value(self, fn(self, *args, **kwargs))
                              ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "apps/frappe/frappe/model/document.py", line 1130, in fn
    return method_object(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "apps/frappe/frappe/website/doctype/website_theme/website_theme.py", line 51, in validate
    self.generate_bootstrap_theme()
  File "apps/frappe/frappe/website/doctype/website_theme/website_theme.py", line 112, in generate_bootstrap_theme
    process = Popen(command, cwd=frappe.get_app_source_path("frappe"), stdout=PIPE, stderr=PIPE)
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/workspace/.pyenv/versions/3.12.0/lib/python3.12/subprocess.py", line 1026, in __init__
    self._execute_child(args, executable, preexec_fn, close_fds,
  File "/workspace/.pyenv/versions/3.12.0/lib/python3.12/subprocess.py", line 1950, in _execute_child
    raise child_exception_type(errno_num, err_msg, err_filename)
FileNotFoundError: [Errno 2] No such file or directory: 'node'

I think the problem is related to missing node in the configured path for this functionality.

To Reproduce

  1. edit a website theme
  2. click save
  3. error is thrown

Expected behavior Save the website theme.

System information (please complete the following information):

  • [0.18.0 ] fm --version
  • [LSB Version: n/a Distributor ID: AlmaLinux Description: AlmaLinux 9.6 (Sage Margay) Release: 9.6 Codename: n/a ] lsb_release -a
  • [ Client: Docker Engine - Community Version: 28.4.0 API version: 1.51 Go version: go1.24.7 Git commit: d8eb465 Built: Wed Sep 3 21:00:35 2025 OS/Arch: linux/amd64 Context: default Server: Docker Engine - Community Engine: Version: 28.4.0 API version: 1.51 (minimum version 1.24) Go version: go1.24.7 Git commit: 249d679 Built: Wed Sep 3 20:57:19 2025 OS/Arch: linux/amd64 Experimental: false containerd: Version: 1.7.27 GitCommit: 05044ec0a9a75232cad458027ca83437aae3f4da runc: Version: 1.2.5 GitCommit: v1.2.5-0-g59923ef docker-init: Version: 0.19.0 GitCommit: de40ad0 ] docker version
  • [Docker Compose version v2.39.2 ] docker-compose version or docker compose version

victorarocha avatar Sep 18 '25 18:09 victorarocha

After digging in the error, I found that frappe is looking for node in this locations: executable_list = (b'/opt/user/.bin/node', b'/usr/local/sbin/node', b'/usr/local/bin/node', b'/usr/sbin/node', b'/usr/bin/node', b'/sbin/node', b'/bin/node')

But the frappe-manager container does not have node in any of those paths.

Executing which node inside the bench (fm shell _benchname_ ) shows /workspace/.nvm/versions/node/v22.18.0/bin/node

As a workaround I created a symlink, inside the bench: ln -s /workspace/.nvm/versions/node/v22.18.0/bin/node /opt/user/.bin/node

Now, saving a Website theme is working as expected 🎉

Any comments on a better solution ?

victorarocha avatar Sep 18 '25 21:09 victorarocha

Currently the node in the container is managed by nvm. I think nvm is not loading in this case. Check if NVM is again loading in .zshrc or .bashrc,if exits then remove it. Need to check why this might be happening ? Have you migrated from v17 or this is new site in v18 ?

Xieyt avatar Sep 21 '25 15:09 Xieyt

Currently the node in the container is managed by nvm. I think nvm is not loading in this case. Check if NVM is again loading in .zshrc or .bashrc,if exits then remove it. Need to check why this might be happening ? Have you migrated from v17 or this is new site in v18 ?

Hello @Xieyt

Yes, I migrated from v17

Here is the content of .zshrc inside the container (fm shell benchname) :

# If you come from bash you might have to change your $PATH.
# export PATH=$HOME/bin:/usr/local/bin:$PATH
export PATH=$HOME/.local/bin:$PATH

# Path to your oh-my-zsh installation.
export ZSH=$HOME/.oh-my-zsh

ZSH_THEME="fm"

plugins=(git z)

source $ZSH/oh-my-zsh.sh

export LC_ALL=en_US.UTF-8
export LANG=en_US.UTF-8
export LANGUAGE=en_US.UTF-8
export EDITOR='vim'

# history settings
HISTSIZE=10000000
SAVEHIST=10000000
setopt BANG_HIST                 # Treat the '!' character specially during expansion.
setopt EXTENDED_HISTORY          # Write the history file in the ":start:elapsed;command" format.
setopt INC_APPEND_HISTORY        # Write to the history file immediately, not when the shell exits.
setopt SHARE_HISTORY             # Share history between all sessions.
setopt HIST_EXPIRE_DUPS_FIRST    # Expire duplicate entries first when trimming history.
setopt HIST_IGNORE_DUPS          # Don't record an entry that was just recorded again.
setopt HIST_IGNORE_ALL_DUPS      # Delete old recorded entry if new entry is a duplicate.
setopt HIST_FIND_NO_DUPS         # Do not display a line previously found.
setopt HIST_IGNORE_SPACE         # Don't record an entry starting with a space.
setopt HIST_SAVE_NO_DUPS         # Don't write duplicate entries in the history file.
setopt HIST_REDUCE_BLANKS        # Remove superfluous blanks before recording entry.
setopt HIST_VERIFY               # Don't execute immediately upon history expansion.
setopt HIST_BEEP                 # Beep when accessing nonexistent history.


# awesome cd movements from zshkit
setopt autocd autopushd pushdminus pushdsilent pushdtohome cdablevars
DIRSTACKSIZE=5

# Auto update Oh My ZSH without asking for confirmation
DISABLE_UPDATE_PROMPT=true

# aliases
alias fm='/opt/.pyenv/shims/bench'
alias fm='/opt/.pyenv/shims/bench'
[[ -f ~/.zsh_aliases ]] && source ~/.zsh_aliases
export PATH="/opt/user/.bin:$PATH"

victorarocha avatar Sep 22 '25 20:09 victorarocha