Claude Code: Fix zsh Permission Denied Errors
A "permission denied" error when running Claude Code in zsh usually has one of three causes: a missing executable bit, an installation ownership problem, or a PATH issue. Here is how to diagnose each one before you change anything.
Updated 5 min read
A "permission denied" error when running Claude Code in zsh usually has one of three causes: the executable bit is missing on the binary, the installation directory is owned by the wrong user, or the PATH is pointing at a broken symlink. Tools like fenbs let you record the confirmed fix as a project lesson so teammates — and future AI sessions — do not spend time re-diagnosing the same problem.
Diagnose before you change anything. Changing permissions without understanding the cause can make the problem harder to fix or introduce a new one.
Step one: locate the binary
Find out which claude binary zsh is trying to run:
which claude
If which returns nothing, the binary is not on your PATH. If it returns a path, note it — you will check that path in the next steps.
If which returns a path but running claude still gives "permission denied," the binary exists but is not executable, or you do not own it.
Step two: check the executable bit
Inspect the file permissions on the binary:
ls -la $(which claude)
The output shows who owns the file and which permissions are set. A file missing the executable bit looks like -rw-r--r-- rather than -rwxr-xr-x. The x in each segment means executable.
If the executable bit is missing and you own the file, add it:
chmod +x $(which claude)
Do not add the executable bit to a file you do not own. That requires sudo and changes a file outside your user space. Understand why the bit is missing first.
Step three: check installation ownership
Claude Code is typically installed via npm or npx. If it was installed with sudo npm install -g, the files are owned by root. Running it as a normal user gives "permission denied" because you do not own the binary.
ls -la $(which claude)
If the owner is root and you are not root, reinstall without sudo. First, check where npm installs global packages for your user:
npm config get prefix
If the prefix is /usr/local or /usr, it requires root. The fix is to change the npm global directory to a path you own — typically ~/.npm-global — and reinstall. Instructions are in the npm documentation (opens in a new tab). For Claude Code installation steps, see how to install Claude Code.
Step four: check for a broken symlink
which claude can return a symlink. If the target of the symlink no longer exists — for example, after uninstalling an earlier version — zsh finds the link but cannot execute the target.
ls -la $(which claude)
A line like claude -> /usr/local/lib/node_modules/@anthropic-ai/claude-code/bin/claude shows a symlink. Follow the link and check whether the target exists:
ls -la /usr/local/lib/node_modules/@anthropic-ai/claude-code/bin/claude
A "No such file or directory" means the target is gone. Reinstalling Claude Code recreates both the binary and the symlink.
Step five: zsh PATH and shell configuration
zsh reads PATH from ~/.zshrc, ~/.zprofile and /etc/paths. If the binary is in a directory that is not on your PATH, zsh cannot find it. Print your current PATH:
echo $PATH
Check whether the directory containing claude is listed. If not, add it to ~/.zshrc:
export PATH="$HOME/.npm-global/bin:$PATH"
After editing ~/.zshrc, reload it with source ~/.zshrc and run which claude again.
Record the fix so teammates don't repeat the diagnosis
Once you find the root cause, add it as a lesson in fenbs: what the error looked like, what caused it (root-owned installation, missing executable bit, broken symlink), and the exact commands that fixed it. Link it to the project. The next developer — or the next AI session — checks lessons before similar work and skips straight to the fix.
Create a free accountFree for one person · No credit card · Works with Claude, ChatGPT, Cursor and more
What not to do
Do not run sudo chmod 777 on the Claude Code binary or its parent directory. This removes all file permission protection and is not needed. Each of the causes above has a targeted fix that does not require broad permission changes.
Do not add Claude Code to sudoers to run it as root. The tool edits files in your codebase; running it as root gives it root access to the whole system.
Do not delete and reinstall before diagnosing. Reinstalling over a root-owned installation may leave the same ownership problem in place.
Record the npm prefix path, the shell config file used, and any environment-specific setup decisions as context notes in a shared record. The next session — yours or a colleague's — reads those facts rather than rediscovering them. Setup decisions that affect every developer belong in the shared record.
How to do this with fenbs
- Create a free account and add the project.
- After resolving the error, record the root cause and the fix as a lesson in fenbs, linked to the project.
- Add the npm prefix path and the relevant shell config as a context note so the next setup on a new machine starts from confirmed facts.
- Connect Claude Code from Integrations. In future sessions, Claude Code reads the context notes and lessons before troubleshooting similar issues.
For more on Claude Code installation and documentation, see how to install Claude Code and Claude Code docs.
After the fix: prevent recurrence
Once you have identified and fixed the root cause, add a note to your team's setup documentation. If the cause was a root-owned npm installation, document the correct install steps so the next person on a new machine does not repeat the mistake. A one-paragraph note in the project's onboarding guide is faster than re-diagnosing this for every new developer.
If you use a shared machine or a shared CI environment where Claude Code is installed, record who owns the binary, which npm prefix is used, and which shell config adds it to the PATH. These facts change when a machine is updated or when a different user installs a newer version.