My Laravel PR Was Auto-Closed in 16 Seconds — 3 Lessons From Contributing to laravel/framework
I recently backported a routing fix from Laravel 13.x to 12.x. The code change was 64 lines, all tests passed locally — and a bot still closed my PR 16 seconds after I opened it.
Here's what happened and the three things I'll do differently next time.
The task: a clean 1:1 backport
Issue #61788 reported that on 12.x, ? in route parameters gets encoded (? → %3F), breaking URLs built with pre-encoded values. The fix had already landed on 13.x as PR #61610, which introduced a tiny EncodedParameter wrapper so already-encoded values pass through RouteUrlGenerator::encodeParameter() untouched.
The 12.x branch had the exact pre-fix code, so the port was mechanical: one new file, a short-circuit in encodeParameter(), and the regression test copied over. RoutingUrlGeneratorTest: 59 tests, 286 assertions, all green. Pint clean. I opened the PR feeling good.
Sixteen seconds later, it was closed. Not by a human — by github-actions[bot].
Lesson 1: Tick "Allow edits from maintainers" or don't bother
The bot's message:
We require that all PRs grant maintainer edit access before we review them… Please resubmit this PR from a personal GitHub account with maintainer permissions enabled.
Laravel won't even look at a PR without the "Allow edits from maintainers" checkbox. When you open PRs from the GitHub web UI on your own fork, the box is usually ticked by default — but I created mine via the API, where it defaults to off.
If you automate PR creation (scripts, API, bots), set maintainer_can_modify: true explicitly. I resubmitted as #61871 with the flag on, and the bot left it alone. One checkbox, sixteen seconds, an entire round-trip wasted.
Lesson 2: Check for existing PRs before writing a single line
Before picking the backport, I had shortlisted three issues — and two were already being handled:
-
#61848 (
logoutOtherDevicesinvalidating the current session) already had open PR #61851. -
#61216 (truncated
RequestExceptionmessages) had prior PRs attached.
GitHub shows linked PRs right on the issue page (closed_by_pull_requests / linked pull requests section). Thirty seconds of checking saved me from duplicating someone's work. Boring advice, but the backport only existed as an opportunity because I checked.
Lesson 3: Red CI isn't always your fault — prove it
My resubmitted PR came back with a failing PHPStan job: 6 errors in Support/Collection.php and Support/LazyCollection.php about literal generics (<'foo'> vs string). Files I never touched.
Instead of "fixing" unrelated code (never do that in someone else's repo), I ran the exact CI command locally against the clean base commit — no changes of mine at all. It failed too, with pre-existing errors. That proves version drift between the pinned config and the current PHPStan release, not a regression from my change. I posted that evidence as a comment on the PR so maintainers can see at a glance that the red X isn't mine.
The rule: if CI fails in files outside your diff, reproduce it on the base commit before touching anything. A comment with proof ("fails on 71cf667 with zero changes applied") is worth more than a speculative fix.
The takeaway
Contributing to a project like laravel/framework is 20% code and 80% process hygiene:
- Check for competing PRs first.
- Grant maintainer edit access (especially via API).
- When CI blames you for someone else's drift, prove it on a clean tree instead of "fixing" it.
The backport itself? Three files, done in minutes. Everything around it took the afternoon. That's normal — and now it's written down so your afternoon goes faster than mine.
Top comments (0)