When you type a command like func, python, or node, your shell searches locations listed in an environment variable called PATH and runs the first match it finds. If the wrong version runs (e.g., an old npm shim instead of the MSI you installed), you’ll see weird errors.
This guide shows how to check which binary is being used, and how to set PATH (temporarily or permanently) so your shell picks the right one — with examples for PowerShell and bash, and a quick Azure Functions (“func”) case study.
Quick TL;DR (copy/paste)
- Check what you’re running
- PowerShell:
Get-Command func -All where func - bash (Git Bash / macOS / Linux):
which -a func command -v func
- PowerShell:
- Temporarily prefer a directory (session-only)
- PowerShell:
$env:Path = "C:\Program Files\Microsoft\Azure Functions Core Tools;$env:Path" - bash:
export PATH="/c/Program Files/Microsoft/Azure Functions Core Tools:$PATH" # macOS/Linux example: # export PATH="/usr/local/bin:$PATH"
- PowerShell:
- Permanently prefer a directory
- PowerShell (User PATH):
$msi = "C:\Program Files\Microsoft\Azure Functions Core Tools" $usr = [Environment]::GetEnvironmentVariable("Path","User") if ($usr -notlike "*$msi*") { [Environment]::SetEnvironmentVariable("Path", "$msi;$usr", "User") } # refresh current session $env:Path = [Environment]::GetEnvironmentVariable("Path","User") - bash (Git Bash, macOS, Linux):
echo 'export PATH="/c/Program Files/Microsoft/Azure Functions Core Tools:$PATH"' >> ~/.bashrc # macOS zsh default: # echo 'export PATH="/usr/local/bin:$PATH"' >> ~/.zshrc source ~/.bashrc # or: source ~/.zshrc
- PowerShell (User PATH):
What is PATH (and why it breaks)
PATH is an ordered list of directories. Your shell scans them left to right and runs the first matching executable it finds. Common breakages:
- You installed a new tool, but your shell still runs an old shim (e.g., npm/nvm global).
- You have multiple package managers (MSI/winget/choco + npm + pyenv + conda + Homebrew), each dropping its own binary.
- VS Code’s terminal uses a different shell (PowerShell vs Git Bash vs WSL), each with a different PATH.
Rule of thumb: Put the directory you want to win earliest in PATH.
Case Study: Azure Functions Core Tools (func)
Symptoms you might see:
Error: Cannot find module ... azure-functions-core-tools\lib\main.jsfuncruns, but it’s clearly not the MSI you installed.
Diagnosis
- PowerShell:
Get-Command func -All where func - bash:
which -a func
If you see paths under %APPDATA%\npm or C:\nvm4w\nodejs\..., that’s an old npm shim. Prefer the MSI path, e.g.:
C:\Program Files\Microsoft\Azure Functions Core Tools\func.exe
Fix (session-only)
- PowerShell:
$env:Path = "C:\Program Files\Microsoft\Azure Functions Core Tools;$env:Path" func --version - bash (Git Bash):
export PATH="/c/Program Files/Microsoft/Azure Functions Core Tools:$PATH" func --version
Fix (permanent)
- PowerShell (User PATH): see TL;DR above.
- bash/macOS/Linux: add
export PATH="...:$PATH"to your shell RC (~/.bashrc,~/.zshrc), thensourceit.
You don’t have to delete the old shim. PATH order decides which one runs.
Windows: PowerShell tips
- Show current PATH (User):
[Environment]::GetEnvironmentVariable("Path","User") - Show current PATH (Machine):
[Environment]::GetEnvironmentVariable("Path","Machine") - Prepend a path for this session only:
$env:Path = "C:\Your\Tools;$env:Path" - Prepend to User PATH (persists across sessions):
$new = "C:\Your\Tools" $usr = [Environment]::GetEnvironmentVariable("Path","User") if ($usr -notlike "*$new*") { [Environment]::SetEnvironmentVariable("Path", "$new;$usr", "User") } - After editing PATH in System Properties (GUI), you must reopen terminals to pick up changes.
Watch out for: App Execution Aliases (Windows can shadow python, python3, etc.). Disable them if they interfere: Settings → Apps → App Execution Aliases.
Git Bash on Windows
Windows paths become /c/... in Git Bash. Examples:
# Prefer a Windows install for this session
export PATH="/c/Program Files/Microsoft/Azure Functions Core Tools:$PATH"
# Verify
which -a func
func --version
To persist, add the export line to ~/.bashrc (or ~/.profile), then source ~/.bashrc.
macOS & Linux
- Default shell is often zsh (macOS) or bash (Linux).
- Add your preferred directory at the front of
PATHin your RC file:# macOS (zsh) echo 'export PATH="/usr/local/bin:$PATH"' >> ~/.zshrc source ~/.zshrc # Linux (bash) echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.bashrc source ~/.bashrc - Verify:
which -a python which -a node which -a func
VS Code terminals (important)
VS Code’s integrated terminal inherits the environment of the shell you choose:
- If your fixes are in PowerShell, open a PowerShell terminal in VS Code.
- If your fixes are in Git Bash, open a Git Bash terminal.
- After changing PATH or RC files, either Reload Window or open a new terminal to apply changes.
WSL (Windows Subsystem for Linux)
WSL is a separate Linux environment with its own PATH and tools. A Windows install in C:\Program Files\... won’t automatically be on WSL’s PATH.
- Install tools inside WSL (e.g., via
apt,brew, or direct downloads). - Verify with:
which -a func func --version
Verification & rollback
- Verify the active binary:
- PowerShell:
Get-Command <tool> -All - bash:
which -a <tool>
- PowerShell:
- If something breaks, remove the line you added to PATH in your RC file and reopen the terminal.
Common PATH “gotchas” (and fixes)
- Multiple Python installs (
python,py, Anaconda, Store app): pick one, put itsScripts/and root dir first, and disable Windows App Execution Aliases if needed. - nvm vs Node MSI: ensure the desired Node’s
binfolder is first. For nvm-windows, runnvm use <version>per session or set a default. - pip vs pip3: explicitly use
python -m pip install ...to ensure you’re installing into the current interpreter.