Why Your Workflow Is Silently Doing Nothing
GitHub Actions is way more layered than people realize with all the configuration noise flying around. You push code. You wait. Nothing happens — no error, no failed run in the Actions tab, no indication anything went wrong. Just silence. That specific flavor of failure is uniquely maddening in DevOps.
As someone who spent three hours last month staring at an empty Actions dashboard only to discover my workflow file was sitting in .github/workflow/ instead of .github/workflows/, I learned everything there is to know about diagnosing silent trigger failures. One missing letter. Three hours. Today, I will share it all with you.
The diagnostic mindset matters more than memorizing edge cases here. GitHub Actions doesn’t yell when a trigger condition is never met. The job simply never runs. No crime scene. No evidence.
The fix requires confirmation at each layer — did the trigger event fire? Is the workflow file readable? Do permissions allow execution? Does the branch match the filter? Work through these five causes in order. Most workflows fail for the first two reasons.
Check Your Workflow File Location and Name First
Okay, here’s the thing nobody tells you.
GitHub Actions only recognizes workflow files in exactly one place: .github/workflows/ at the repository root. Not .github/workflow/. Not .workflows/. Not nested inside a subdirectory. The path is strict — and case-sensitive on Linux runners, which is most of them.
If your YAML file sits anywhere else, GitHub never loads it. No warning. No failure state. The file simply doesn’t exist as far as Actions is concerned.
Verify your file location immediately:
git ls-files.github/workflows/
This lists every file GitHub is actually tracking in that directory. If your workflow file doesn’t appear here, it’s either in the wrong path or you haven’t committed it yet. Uncommitted files in your local directory won’t trigger anything — GitHub reads from the repository, not your machine.
Confirm the file exists and is tracked:
git log --oneline --.github/workflows/your-workflow.yml
If that returns nothing, the file has never been committed. Push it to your default branch first. That was probably the whole problem.
One more quick check — verify the YAML syntax is valid:
python -m yaml.github/workflows/your-workflow.yml
A syntax error prevents GitHub from parsing the file at all. No runs appear. No status. Just that same infuriating nothing.
Branch Filters and Event Types Are Usually the Real Problem
I’m apparently very good at writing branch filters that exclude the exact branch I’m working on. Don’t make my mistake.
Branch filters are the single most common culprit when GitHub Actions workflows silently fail to trigger. The YAML looks right. The file is in the right place. But the workflow never runs because your branch name doesn’t match the filter — and GitHub isn’t going to tell you that.
Here’s a broken example:
name: Deploy to Production
on:
push:
branches:
- main
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
This workflow only triggers on pushes to main. Push to develop, staging, or feature/new-api and nothing happens. The workflow isn’t broken. It’s working exactly as configured. That’s what makes the silent failure so endearing to us developers debugging at 11pm.
Verify your current branch:
git branch --show-current
Now compare that name to the branches: filter in your YAML. Exact match required. main will not match Main. Main will not match master. No flexibility, no forgiveness.
Glob patterns do work here, though. This configuration triggers on any branch starting with release/:
on:
push:
branches:
- 'release/**'
Another trap worth knowing: on: pull_request and on: pull_request_target are not interchangeable. pull_request runs in the context of the PR branch and has access to secrets. pull_request_target runs against the base branch — safer for forks, but no secrets by default. If you’re expecting workflows to trigger on fork pull requests using pull_request, they won’t run. Full stop.
Here’s the corrected version that covers the main cases:
name: Deploy to Production
on:
push:
branches:
- main
- 'release/**'
pull_request:
branches:
- main
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
This runs on pushes to main, any release/ branch, and pull requests targeting main. So, let’s move to the next layer.
Permission and Token Issues That Block Workflow Runs
Even when the trigger fires and the file is in the right place, permissions can silently stop execution cold.
Every workflow run uses the default GITHUB_TOKEN unless you configure a different one. That token’s scope varies by repository settings. In a lot of setups — public repos especially — it defaults to read-only. Any job that needs to write code, create releases, or open pull requests hits a wall it never reports hitting.
Navigate to Settings > Actions > General > Workflow permissions in your repository. Check what’s set:
- Read repository contents and packages: Read-only. Most trigger problems aren’t here, but if your job needs write access, this is the wall.
- Read and write permissions: Full scope for your workflow’s default token.
For public repositories, read-only is the default. Change this if your workflow modifies code or pushes commits — at least if you want those steps to actually execute.
Fork PRs add another layer. GitHub suppresses secrets and limits token permissions on fork pull requests by default. That’s a security decision, not a bug. Navigate to the same Workflow permissions section and check Allow GitHub Actions to create and approve pull requests if your workflow needs to open PRs as part of execution.
These settings don’t always block the trigger entirely. Sometimes they cause the job to fail before it logs anything visible. Either way, the result looks the same from the outside — nothing happened.
Still Not Firing — Use the Actions API to Confirm
If the file is in the right place, the branch matches, and permissions look fine, but the workflow still never runs — use GitHub’s CLI to check the backend directly. Hunting through the web interface at this point is a waste of time.
The GitHub CLI gives you direct access to the Actions API:
gh run list --workflow=your-workflow.yml
This returns all runs for that specific workflow, ordered by date. Empty list means the trigger never fired. Runs showing a skipped status mean something else blocked execution — usually a job condition or a path filter you forgot about.
To see exactly why a run was skipped:
gh run view [run-id] --log
Replace [run-id] with the ID from the run list output. The log shows you precisely why GitHub decided not to execute the job. That’s usually enough to close the case.
Before escalating or opening an issue, run through this checklist in order:
- Workflow file is in
.github/workflows/and committed to your default branch. - YAML syntax is valid with no indentation errors.
- The event type in
on:matches the action you’re actually testing — push, pull_request, schedule, whatever. - Branch name matches the filter exactly, or the filter uses a valid glob pattern.
- Repository permissions under
Actions > General > Workflow permissionsallow the required access level.
Most workflows that mysteriously stop triggering will fail at step 2 or 3. Five minutes of verification against this list saves hours of debugging later. I’ve run this checklist enough times to know that’s not an exaggeration.
Leave a Reply