Sunday afternoon. Coffee’s warm, the sun is out, and I’ve got six open pull requests on OpenClaw — the AI agent framework. What could go wrong?
Everything. Everything could go wrong.
Act I: The Reviews Arrive
After days of radio silence, the bots woke up. Greptile, Codex, Copilot — all of them decided that today was the day to have opinions about my code. 47 review comments across 6 PRs. At once.
Let’s look at what they had to say:
PR #45348 — PostgreSQL + pgvector Memory Backend
The big one. A full vector memory backend for OpenClaw with pgvector, embedding sync, and re-embed on model change. Greptile was concerned about:
-
“Silent fallback can mask misconfiguration” — Fair point. If postgres fails to init, it falls back to the default backend without screaming. I added explicit warning logs. You want to know when your shiny vector DB isn’t actually running.
-
“Plaintext credentials stored as map key” — The connection string (with password) was used as a Map key for caching managers. Yikes. Switched to a hashed key.
-
“No shutdown cleanup” — Pool connections just… hung around forever. Added a
closeAllMemorySearchManagers()hook on process exit. Databases appreciate it when you say goodbye properly.
PR #45207 — Headless Browser Mode
This one lets you run browser tools without a visible window. Codex flagged:
- “State mutation persists beyond the operation” — I was setting
headless: trueon the resolved profile config and never unsetting it. So if you ran headless once, every subsequent launch was headless too. Whoops. Switched to a save/restore pattern — override for the current operation, then put everything back.
PR #46533 — SSRF Protection for Camera Nodes
Security fix for Server-Side Request Forgery. The original approach blocked all private network IPs. Reviewer pointed out: “Nodes in LANs typically have private IPs.” Right. Blocking 192.168.x.x when your entire fleet lives on 192.168.x.x is… suboptimal. Redesigned it to use a hostnameAllowlist instead.
PR #46538 — Proxy Support for Web Tools
A one-liner: useEnvProxy: true. But the DNS pinning discussion was interesting — when traffic goes through a proxy, you can’t pin DNS because the proxy resolves the hostname. Added a code comment explaining the conscious tradeoff rather than pretending it’s not there.
PRs #45174 & #33466 — The Quiet Ones
Env blocklist extension and HTTP 400 delivery error handling. Small, focused, boring. The kind of PRs that make infrastructure reliable. No drama here.
Yet.
Act II: The Response Marathon
47 comments needed 47 thoughtful replies. Not generic “Fixed, thanks!” responses — real explanations of what changed and why. Each one referencing the specific commit. Because maintainers can smell drive-by “I’ll fix it later” promises from three repos away.
✅ PR #45348 — 6 comments addressed
✅ PR #45207 — 4 comments addressed
✅ PR #46533 — 3 comments addressed
✅ PR #46538 — 2 comments addressed
✅ PR #45174 — 1 comment addressed
✅ PR #33466 — 1 comment addressed
Feeling good. Feeling productive. Time for a quick branch update…
Act III: The Rebase Disaster
Four of the six PRs? Clean. MERGEABLE. No problems.
PRs #45174 and #33466? CONFLICTING.
“No worries,” I thought. “Just a quick rebase onto main.”
$ git rebase upstream/main
# ... 847 conflicts in 847 files
Eight hundred and forty-seven files.
See, here’s what happened: GitHub’s “Update branch” button had been merging main into my feature branches for weeks. Each sync pulled in hundreds of upstream commits. My branches weren’t “my changes on top of main” — they were an archaeological dig site with layers of merge commits, upstream changes, and my actual code buried somewhere in the middle.
Rebasing this was like trying to iron a sweater that’s been through a washing machine, a dryer, and a small tornado.
Act IV: The Cherry-Pick Salvation
Time for Plan B. Instead of rebasing the Frankenstein branches, I went surgical:
# Find ONLY my commits in the mess
git log upstream/main..origin/fix/env-blocklist-incomplete \
--oneline --no-merges --author="Benedikt"
# → 1 actual commit. ONE. Among hundreds.
# Fresh branch from upstream/main
git checkout -b env-clean upstream/main
# Cherry-pick just my work
git cherry-pick 7a9665bec
# Force push the clean branch
git push origin env-clean:fix/env-blocklist-incomplete --force
Same for the delivery errors PR: 2 commits. That’s it. Two commits buried under an avalanche of fork-sync noise.
Result:
- PR #45174: 2 files changed (was: 847 files in conflict)
- PR #33466: 2 files changed (was: probably similar carnage)
Clean. Surgical. Beautiful.
Lessons Learned
-
Never use GitHub’s “Update branch” merge button repeatedly. It creates an ever-growing ball of merge commits. Rebase locally or accept your fate.
-
git log --authoris your best friend when your branch has been contaminated with upstream commits. Find your needles, ignore the haystack. -
Cherry-pick > rebase when a branch has diverged beyond recognition. Start fresh, pick clean.
-
Reply to every review comment individually. It shows you actually read the feedback and didn’t just push random fixes hoping they match.
-
Sunday afternoon PRs hit different. The bots have been accumulating opinions all week and they release them all at once, like a dam breaking.
Current Status
All six PRs are clean, rebased, and up-to-date:
| PR | Branch | Status |
|---|---|---|
| #45348 | feat/postgres-memory-backend-v2 |
✅ Clean |
| #45207 | feat/browser-headless-mode |
✅ Clean |
| #45174 | fix/env-blocklist-incomplete |
✅ Rebased |
| #46533 | fix/ssrf-nodes-camera |
✅ Clean |
| #46538 | fix/proxy-support-web-tools |
✅ Clean |
| #33466 | fix/permanent-delivery-errors-http-400 |
✅ Rebased |
Now we wait for the human maintainers. The bots have had their say. Time for the people who can actually click “Merge.”
Wish me luck. 🐉
This post is part of my ongoing OctoFleet and open-source journey. More war stories at schackenberg.com.