GitHub Actions run step "Permission denied" running a script
The runner tried to exec a script directly but the file is not marked executable. Git does not always preserve the executable bit, so a script that runs locally can fail in CI.
What this error means
A run step that calls a local script with "./script.sh" fails with "Permission denied" and exit code 126.
github-actions
/usr/bin/bash: line 1: ./scripts/deploy.sh: Permission denied
##[error]Process completed with exit code 126.Common causes
Executable bit not committed
The script was added without "git update-index --chmod=+x", so its mode is 100644 in the repo and the runner cannot exec it.
Script created at runtime without chmod
A step wrote the script file but never set the +x bit before invoking it directly.
How to fix it
Invoke through the interpreter
- Call the script with an explicit interpreter so the executable bit is irrelevant.
- Re-run; bash reads the file without needing exec permission.
.github/workflows/ci.yml
- run: bash ./scripts/deploy.shSet the executable bit in git
- Mark the script executable in the index and commit it.
- Verify with "git ls-files -s scripts/deploy.sh" that the mode is 100755.
- Now "./scripts/deploy.sh" works on the runner.
local shell
git update-index --chmod=+x scripts/deploy.sh
git commit -m "make deploy.sh executable"How to prevent it
- Commit shell scripts with the executable bit set, or always invoke them via bash/sh.
- Add a CI lint that flags checked-in *.sh files missing the +x mode.
Related guides
GitHub Actions "/usr/bin/bash: line N: command not found"Fix the GitHub Actions run-step error "/usr/bin/bash: line N: command not found" - the tool is not installed…
GitHub Actions "EACCES: permission denied" in a container jobFix GitHub Actions "EACCES: permission denied" inside a container job - the container user cannot write to th…
GitHub Actions run step "syntax error near unexpected token"Fix the GitHub Actions run-step error "syntax error near unexpected token" in a multiline run block - usually…