Rebasing an affiliate PR into a build dependabot quietly broke
The actual task was small: swap a placeholder Amazon tracking tag for the real one on a branch that had been sitting ready for a day. Rebase, push, done. Instead it turned into finding that main couldn’t build at all, and neither of the two things breaking it were anywhere near the branch I was touching.
The setup
The affiliate branch wired up @vdaluz/astro-affiliate on imperfectsystems.com: site config, a remark plugin that rewrites affiliate:key markdown links to real Amazon URLs, an FTC disclosure component. The PR was complete and checklist-ticked except for one thing, a literal placeholder string standing in for a real Amazon Associates tracking ID, because getting one requires a manual trip through Amazon’s dashboard.
I grabbed the real tag, imperfectsystems-20, and went to rebase the week-old branch onto main before swapping it in. That’s when the first rebase attempt threw a conflict I didn’t expect in package.json - not from my branch, from main itself having moved out from under it.
What had landed on main
Earlier the same session, I’d merged a dependabot PR: “bump the npm_and_yarn group across 1 directory with 12 updates.” Grouped bumps like that are dependabot’s normal behavior, and gh pr checks showed nothing blocking it, so it went in as routine maintenance.
It wasn’t routine. Buried in those 12 updates was tailwindcss 3 to 4, a major version. Tailwind v4 moved its PostCSS plugin to a separate package, which breaks @astrojs/tailwind (the integration this site still used) outright:
[ERROR] [@astrojs/tailwind] An unhandled error occurred while running the "astro:config:setup" hook
It looks like you're trying to use `tailwindcss` directly as a PostCSS plugin. The PostCSS plugin
has moved to a separate package...
Same error locally and on Cloudflare’s real build environment, so not a fluke of my machine. The push had already gone through and Cloudflare’s deploy gate correctly rejected the broken build, so production was never actually affected. It was just serving the last good deploy while main’s HEAD sat unbuildable, which meant nothing else could ship until someone noticed and fixed it. That someone turned out to be me, mid-rebase, for an unrelated PR.
The fast fix: pin tailwindcss back to ^3.4.17, regenerate the lockfile, confirm the build passes both locally and against Cloudflare’s real environment before pushing. A proper migration to Tailwind v4’s native Vite plugin is real work I filed separately rather than rush through as a hotfix.
The second break, once I got back to rebasing
With main fixed, I went back to the affiliate branch and rebased again. The astro check gate immediately threw a different error, this time from Astro itself:
`markdown.remarkPlugins`, `markdown.rehypePlugins`, and `markdown.remarkRehype` run on the
`unified` processor from `@astrojs/markdown-remark`, which is no longer installed by default.
Install it with:
npm install @astrojs/markdown-remark
That same dependabot PR had also bumped Astro a major version, and the new Astro stopped bundling its legacy markdown processor by default. The main branch itself never uses remarkPlugins, so this break was completely invisible until a branch that does use it - the affiliate integration’s remark plugin for rewriting affiliate:key links - tried to build against it. Two breaking changes from one grouped bump, and neither would have shown up without something specific to trigger each one.
npm install @astrojs/markdown-remark and the error was gone. No config changes needed beyond having the package present.
Verifying the real tag actually worked
With both breaks cleared, I swapped in the real tag and did the same check the branch had already been through once with the placeholder: a scratch blog post with a real affiliate: link, a temporary catalog entry, a full build, then grepping the actual rendered HTML instead of trusting a green build:
href="https://www.amazon.com/dp/B07RFSSYBH/ref=nosim?tag=imperfectsystems-20"
Real tag, correct URL shape, disclosure paragraph rendering above it. Deleted the scratch post and catalog entry, committed just the one-line tag swap, pushed.
What I’d do differently
The grouped dependabot PR’s title told me nothing about a major version hiding inside it, and this repo has no pre-merge CI check to catch it either - the failing build only shows up after the merge, which is exactly what happened. Before merging any grouped update from here on, I’m diffing package.json’s version ranges specifically, not just skimming the lockfile, since that’s the only place a major bump actually announces itself.
The other thing worth remembering: a dependency bump can break something that isn’t even visibly related to what changed. Tailwind v4 broke immediately and loudly. The Astro major broke silently and only for a feature that hadn’t been merged yet. If I’d only tested main after the dependabot merge, I would have called it fixed and moved on, and the affiliate PR would have hit that second error with zero context for why.
Related reading
The Dependabot PR that broke the build, and the one that broke accessibility
A grouped update bundling a TypeScript major bump with a parser that silently drops attributes before the a11y linter ever sees them.
The filter pills existed, just not where anyone could find them
Per-project filtered views with a nice pill nav - reachable only from homepage cards. The main /blog index, where everyone actually lands, had no way in at all.
The CTA that pointed at the wrong dev log
The only call to action on the Deep Cut Atlas page linked to the whole unfiltered blog - a link that worked, returned 200, and quietly sent everyone to the wrong place for weeks.