Unitech/pm2 · error · Error

Interpreter ${app.exec_interpreter} is NOT AVAILABLE in PATH

Error message

Interpreter ${app.exec_interpreter} is NOT AVAILABLE in PATH. (type 'which ${app.exec_interpreter}' to double check.)

What it means

Before launching an app, PM2 verifies the configured exec_interpreter is resolvable via which(). If not found it throws to prevent a silent spawn failure — except for the special 'node' case, which falls back to the bundled node interpreter. Any other missing interpreter aborts.

Source

Thrown at lib/Common.js:464

  if (app.exec_interpreter.indexOf('python') > -1)
    app.env.PYTHONUNBUFFERED = '1'

  if (app.exec_interpreter == 'lsc') {
    app.exec_interpreter = path.resolve(__dirname, '../node_modules/.bin/lsc');
  }

  if (app.exec_interpreter == 'coffee') {
    app.exec_interpreter = path.resolve(__dirname, '../node_modules/.bin/coffee');
  }

  if (app.exec_interpreter != 'none' && which(app.exec_interpreter) == null) {
    // If node is not present
    if (app.exec_interpreter == 'node') {
      Common.warn(`Using builtin node.js version on version ${process.version}`)
      app.exec_interpreter = cst.BUILTIN_NODE_PATH
    }
    else
      throw new Error(`Interpreter ${app.exec_interpreter} is NOT AVAILABLE in PATH. (type 'which ${app.exec_interpreter}' to double check.)`)
  }

  return app;
};

Common.deepCopy = Common.serialize = Common.clone = function(obj) {
  if (obj === null || obj === undefined) return {};
  return fclone(obj);
};

Common.errMod = function(msg) {
  if (process.env.PM2_SILENT || process.env.PM2_PROGRAMMATIC === 'true') return false;
  if (msg instanceof Error)
    return console.error(msg.message);
  return console.error(`${cst.PREFIX_MSG_MOD_ERR}${msg}`);
}

Common.err = function(msg) {

View on GitHub (pinned to 31adee8048)

Solutions

  1. Install the interpreter and ensure it is on PATH for the PM2 daemon, then restart the daemon (pm2 kill && pm2 resurrect).
  2. Reference the interpreter by absolute path.
  3. Set interpreter:'none' if the script is directly executable.
  4. For node-based apps use interpreter:'node' to hit the bundled-node fallback.

Example fix

// before
{ script: 'main.py', interpreter: 'python3' }
// after
{ script: 'main.py', interpreter: '/usr/bin/python3' }
Defensive patterns

Strategy: validation

Validate before calling

const which = require('which');
function resolveInterpreter(interp) {
  if (!interp || interp === 'none') return interp;
  if (which(interp, { nothrow: true }) == null && interp !== 'node') {
    throw new Error(`Interpreter '${interp}' not found on PATH; install it or use an absolute path`);
  }
  return interp;
}
app.exec_interpreter = resolveInterpreter(app.exec_interpreter);

Type guard

const interpreterAvailable = (i) => !i || i === 'none' || i === 'node' || which(i, { nothrow: true }) != null;

Prevention

When it happens

Trigger: Setting interpreter to a runtime that isn't installed or isn't on the PM2 daemon's PATH (python3, php, ruby, deno, ts-node), or misspelling the interpreter name.

Common situations: Container missing the runtime; local dev where the interpreter is installed via nvm/asdf but PATH isn't propagated to the (already-running) PM2 daemon; typo in interpreter.


AI-assisted analysis of Unitech/pm2@31adee8048 (2026-08-13). Data as JSON: /api/errors/1e6584d1a2b8cf73. Report an issue: GitHub.