status conclusion elapsed
completed failure 2s
completed failure 1s
completed failure 3s
completed failure 2s
Four CI runs.
Every one red.
Every one dead in under three seconds.
No build. No tests. No lint.
I spent twenty minutes reading my own diff for the bug.
There was no bug.
The repo was private, and it had run out of free Actions minutes.
I had green checks for two days.
Then red checks for the better part of a week.
The last green run was the 23rd. By the 25th every check was failing. It stayed red until the monthly minutes reset on the 1st.
Nothing in the code changed across that line.
A quota death wears a code failure's face
This is the part that wastes your afternoon.
A real failure and a quota failure paint the same red X on your pull request.
Same icon. Same color. Same sinking feeling.
So you do the rational thing.
You open the diff. You re-read the test. You blame the last commit.
You push a fix that fixes nothing, watch it go red in two seconds, and push another.
The faster the run dies, the more it feels like your code, because a fast failure reads like a fast, obvious mistake.
It is the opposite.
The tell is in the clock, not the logs
Open the run.
A real failure has a body. Steps that started. A step that executed and then failed. A log you can read.
A quota failure has no body at all.
The run is marked failed, the steps list is empty, and the whole thing is over in one to three seconds.
That is the signature.
Failed conclusion, zero steps executed, near-instant finish.
When you see that shape three runs in a row, stop reading your code.
The dispatcher rejected the job before a runner ever picked it up.
You are not looking at a broken build. You are looking at a closed gate.
Why private repos are the ones that bite
Public repositories get unlimited Actions minutes.
Private ones get a free monthly allowance, and the meter is invisible until it hits zero.
There is no warning step. No yellow. No banner telling you that five percent is left while you still have a window to act.
The minutes drain quietly across every push, every scheduled job, every auto-sync hook you wired up to feel productive.
The more automation you bolt onto a private repo, the faster you walk into the wall.
And the wall does not announce itself. It starts answering every push with a two-second red.
The one question that ends the loop
Before you touch the diff, ask one thing.
Did the run actually run.
Open the latest red run and look at whether any step executed.
If steps ran and one failed, it is your code. Read the log.
If no steps ran and it died in seconds, it is the gate. Close the editor.
That single check turns a half-day of phantom debugging into a ten-second diagnosis.
I now run it before I read a single line of my own changes, because my reflex to blame my code is wrong often enough to be dangerous.
What you actually do about it
You have three honest moves, and none of them is push again.
- Flip the repo public if the code can be public. Unlimited minutes, problem gone.
- Wait for the monthly reset if the work can wait. The meter refills on its own.
- Pay for more minutes if it is real production and neither of those fits.
What you do not do is keep firing commits at a closed gate.
Every fix you push while out of minutes is another two-second red that teaches you nothing and convinces you a little harder that your code is haunted.
The green log lies more than the red one
Here is the uncomfortable part.
For two days my checks were green, and I trusted them.
But the green was running on borrowed minutes that were about to run out.
A passing check told me my pipeline was healthy.
What it actually told me was that the meter still had room.
The status icon measures whether the job was allowed to run, not whether your project is sound.
Most of us read a green check as proof of correctness.
It is closer to proof of permission.
The day those two diverge is the day you lose an afternoon to a failure that was never in your code.
Your turn
Go look at your last failed CI run on a private repo.
Did the steps execute, or did it die in two seconds with an empty body.
If you have ever pushed a fix at a run that was never going to run, tell me how long it took you to notice.
For me it was twenty minutes and three commits, and I build CI guardrails for a living.


Top comments (0)