lint-staged: 'lint-staged' is not recognized as an internal or external command, operable program or batch file. (Windows)

Description

When using cmd.exe or Visual Studio Code in Windows I get the error “‘lint-staged’ is not recognized as an internal or external command, operable program or batch file.” when I attempt to commit my changes. Essentially the pre-commit fails because of this. This error does not occur in the Windows Subsystem for Linux command prompt.

Steps to reproduce

  1. Insure you are on a Windows machine with git installed.
  2. Create a project that uses lint-staged
  3. Make a change to your repo.
  4. Using Visual Studio Code or simply cmd.exe, attempt to commit your changes.
  5. You should see the error mentioned above in the console.

Debug Logs

expand to view
> git commit --quiet --allow-empty-message --file -
> git show :package.json
husky > npm run -s precommit (node v8.10.0)

'lint-staged' is not recognized as an internal or external command,
operable program or batch file.

husky > pre-commit hook failed (add --no-verify to bypass)
> git config --get-all user.name
> git config --get-all user.email

Environment

  • OS: Windows 10
  • Node.js: v8.10.0
  • lint-staged: v7.0.0

About this issue

  • Original URL
  • State: open
  • Created 6 years ago
  • Reactions: 13
  • Comments: 25

Commits related to this issue

Most upvoted comments

tl;dr: You might run into this problem on WSL if you’re using an IDE or other tool that is making your commit for you, and that tool uses a Windows version of node/npm.


I’m not sure if this solution will be relevant for some of the other folks in this thread, but I figured out what was going on for me. I noted in my previous comment that I’m using WSL, and that I’m able to commit from the command line, but that Webstorm gives the 'lint-staged' is not recognized error.

I realized it’s because my command line uses a version of node and npm installed on the Windows side of things, not installed in the WSL directories. I ran npm install -g lint-staged in my windows terminal (not in ConEmu, which I have set up to use Fish on WSL). Then I was able to commit normally from Webstorm.

I’m still not completely sure why I needed to install lint-staged globally - I thought that npm scripts would search the local node_modules directory when resolving commands. Anyway, it works fine now.

Thanks @oturpe for the recap - especially workaround no.3. I added npx to every command in husky config (except git related of course). So instead of

"husky": {
    "hooks": {
      "pre-commit": "lint-staged"
    }
  },
  "lint-staged": {
    "./src/**/*.{js,jsx}": [
      "prettier --write",
      "eslint",
      "git add"
    ]
  }

i did:

"husky": {
    "hooks": {
      "pre-commit": "npx lint-staged"
    }
  },
  "lint-staged": {
    "./src/**/*.{js,jsx}": [
      "npx prettier --write",
      "npx eslint",
      "git add"
    ]
  }

Worked like a charm!

@sudo-suhas I deleted node_modules and did an npm install. I was then able to run the precommit command directly in cmd.exe and the precommit worked in VSCode when I committed through the interface. I believe this issue is solved. I recall this issue coming back up eventually, but lets hope it does not come up. If it keeps occurring, I will open a new bug with all the necessary information. Thanks!

Greetings,

I do not think this issue is actually caused by lint-staged.

I ran into this problem, too. In my case, I have node_modules populated from inside WSL shell (using yarn, but I believe using npm would not be any different), but am commiting using Visual Studio Code running in Windows, and have husky set up like this in package.json:

"husky": {
  "hooks": {
    "pre-commit": "lint-staged"
  }
}

Doing git commit from WSL shell, everything works. Somehow husky knows how to find lint-staged from node_modules/.bin, which, since node_modules was populated from WSL shell, is a Unix symlink to …/lint-staged/bin/lint-staged, and runs it successfully.

But Visual Studio Code Git tools (and PowerShell also) run in native Windows, and do not understand the symlink. The reason why populating node_modules again from Windows side works is that in that case node_modules/.bin/lint-staged is a different kind of file. Apparently that file understandable for both WSL shell and Windows (though I think success with Windows may depend on other factors too, like npm config script-shell setting).

Workarounds:

  1. As previously suggested, populate node_modules using Windows. Note that there are other tools (like Lerna) that will not work inside WSL any more if you do this.
  2. Put your source in the WSL file system and run also your IDE from inside WSL. I have not tried this myself, but I believe Visual Studio Code’s remoting feature could do this.
  3. Configure husky like "pre-commit": "yarn lint-staged" (or npx or npm run if you prefer). I am not sure why this makes a difference, but it does - I guess the npm run finds the executable to run differently to what husky does. (Note that with yarn you need to use Node 11 at least, see yarn issue 6086 for details.

I hope this helps.

@okonet I think you can close this issue as non-lint-staged related.

I just got the “‘lint-staged’ is not recognized as an internal or external command” after testing out building on WSL ubuntu. Deleting node_modules and doing npm install from windows side seems to have fixed everything.

I also have this. I tried to do what @Jikodis did but it didn’t help. Any other ideas?

Hey @Jikodis could you try running npm run precommit directly? Because that’s the command which is failing in your pre-commit hook.

pre-commit hook contents
λ cat .\.git\hooks\pre-commit
#!/bin/sh
#husky 0.14.3

command_exists () {
  command -v "$1" >/dev/null 2>&1
}

has_hook_script () {
  [ -f package.json ] && cat package.json | grep -q "\"$1\"[[:space:]]*:"
}

cd "."

# Check if precommit script is defined, skip if not
has_hook_script precommit || exit 0

# Node standard installation
export PATH="$PATH:/c/Program Files/nodejs"

# Check that npm exists
command_exists npm || {
  echo >&2 "husky > can't find npm in PATH, skipping precommit script in package.json"
  exit 0
}

# Export Git hook params
export GIT_PARAMS="$*"

# Run npm script
echo "husky > npm run -s precommit (node `node -v`)"
echo

# The following command is the one which is failing for you.
npm run -s precommit || {
  echo
  echo "husky > pre-commit hook failed (add --no-verify to bypass)"
  exit 1
}

Re-installing both husky and lint-staged could help but I can’t be sure.

Is this bug specific to WSL? Deleting node_modules and then reinstalling doesn’t seem to work. It still keeps occurring.

messed around with this and strictly opening the IDE from within the path in a wsl terminal supresses this issue for me.

TL;DR; MAKE SURE YOU RESTART ALL INSTANCES of VS Code (especially if you use workspaces), and THEN HUSKY will “see” any executable from within NODEJS environment (local ./node_modules/.bin/ or global or any custom NodeJS/npm executable)

WHEN YOU re-install NodeJS packages (during git branches switch for example) where u have Husky v4 and then v6 or v7 or v8, ALSO MAKE SURE TO RESTART VS Code instances !!!

===

I can confirm that I also do have Windows + WSL (Ubuntu) setup and issue with husky and lint-staged and here are my notes while I researched and fixed this issue.

Yes, I do migrate Husky from v4 to v8.

"husky": "^8.0.3",
"lint-staged": "^13.1.2",
  • lint-staged as executable command from .husky/pre-commit doesn’t work whatsoever, and it’s understandable, coz there is no node_modules/.bin/ there (in folder .husky) and lint-staged is NOT installed global npm package (for me).

  • npx lint-staged ALSO WORKS OK, and it’s KINDA better because doesn’t require additional npm adjacent script. But I have some bad feeling using npx when actually lint-staged as package is ALWAYS installed for my project. BUT IF YOU DO NOT INSTALL lint-staged in your local codebase and you DO have Internet connection ALWAYS, then npx approach is 100% for you.

  • npm run lint-staged or npm run lintStaged or any custom NPM script name you create in package.json to target lint-staged WILL work, but…

  • it will NOT work if your forget to clean up REMAINS after Husky v4 in .git/hooks.

image

So I did:

rm .git/hooks/husky.sh && rm .git/hooks/husky.local.sh && rm .git/hooks/pre-commit

and RESTARTED VS Code. Then npm run myCustomLintStage works OK.

Unfortunately such cleanup is NOT done neither by npm install husky -D NOR by npx husky install NOR by npx husky-init

  • You can delete entire folder .git/hooks, which will be REGENARETD after you do git commit/push activity. BUT ANYWAY I do NOT recommend to do so, coz you may have OTHER hooks your project needs, or another developer set it up and you don’t know. ANYWAY MAKE SURE YOU VERIFY ALL carefully before deletion. DO BACKUP ALWAYS !!!

  • I do confirm also, that within node@16.x and npm@8.x you don’t need to execute npm run prepare manually, because it after Husky v8 installed/configured prepare lifecycle hook will be executed similar as postinstall. I would personally remove prepare, but it seems to be reasonable to have, and I don’t want to break future Husky upgrades (if such happen)

AFTER npm install: image

AFTER npm ci: image

More details:

PS. If you have codebase on real Windows and your Husky setup works, and you pushed code to GitHub repo, and then clone on WSL then GET ready to lose permission of file .husky/pre-commit which should be EXECUTABLE.

You will have such warning:

hint: The ‘.husky/pre-commit’ hook was ignored because it’s not set as executable. hint: You can disable this warning with git config advice.ignoredHook false.

To fix that, if you continue using WSL ONLY do this: chmod a+x .husky/pre-commit and then Husky setup will also work on WSL.