All posts
Engineering

AI Agents for Dependency Upgrades: PRs That Get Merged

DevOS Platform TeamJune 22, 202612 min read

Last Tuesday I counted the open PRs in a client's monorepo. Forty-three Renovate PRs. Oldest one: 9 months. The team had configured Renovate perfectly — semantic commit messages, grouped updates by package type, scheduled runs at 3 AM.

Zero merges in Q2.

I wish I could say this was unusual. It's not. Sound familiar? This is the kind of tech debt that piles up silently until it becomes a crisis — and honestly, I've been guilty of ignoring these PRs myself when deadlines get tight.

The problem isn't Dependabot or Renovate. Those tools do exactly what they promise: detect outdated dependencies and open PRs to update them. The problem is everything that happens after. Which is usually nothing. Because everyone's too busy shipping features to babysit version bumps, and let's be real, "review 47 lodash updates" will never make it onto a sprint goal.

The Merge Gap Nobody Talks About

Here's the lifecycle of a typical dependency update PR:

  1. Bot opens PR at 3 AM
  2. CI runs. Tests pass (maybe)
  3. PR sits in the queue
  4. Developer glances at it during standup
  5. "I'll review that later"
  6. Later never comes
  7. Repeat 47 times

The math is brutal. A mid-sized Node.js project with 200 dependencies will generate maybe 10-20 update PRs per week. Some are patch bumps that could merge automatically. Some break tests. Some require code changes because an API got deprecated. And a human developer — already juggling feature work, bug fixes, and meetings — is supposed to review each one?

Ha.

Nobody does. So the PRs pile up. Security vulnerabilities stay unpatched for months. The codebase drifts further behind, and eventually someone spends an entire sprint doing a "dependency cleanup" that should've been 15 minutes of daily maintenance. I've been that someone twice this year. It's not fun, and I'm not proud of how long I let our react-router drift.

Why Auto-Merge Isn't the Answer

Renovate and Dependabot both support auto-merge. Just flip a config flag and updates merge when CI passes. Problem solved?

Not really.

Auto-merge works great when nothing breaks. But dependency updates break things constantly — especially in JavaScript and Python ecosystems where semantic versioning is more of a polite fiction than a contract. A "patch" version that changes behavior. A "minor" version that deprecates the exact function you rely on. A transitive dependency that conflicts with something else. (We see similar patterns in ad tech — bot traffic detection relies on fingerprint versioning that breaks just as often.)

Classic.

When tests fail, auto-merge stops. The PR joins the pile with a red X. Nobody looks at it because nobody has time to investigate why jest threw 3 failures after bumping @testing-library/react from 14.2.1 to 14.2.2. The gap isn't "opening PRs." Dependabot solved that years ago. The gap is "fixing breakage and actually getting PRs to merge."

Enter the Agent Employee

This is where AI agents — the kind that work as assignable team members, not chat assistants — change things. (If you're wondering how multi-agent coordination differs from single-agent coding tools, I wrote about the multi-agent approach to dev workflows separately.)

An agent that handles dependency updates doesn't just open PRs. It does the boring follow-through work that nobody wants to do:

  1. Opens the PR (same as Dependabot/Renovate)
  2. Monitors CI results in real-time
  3. Diagnoses failures when tests break
  4. Reads changelogs and migration guides to understand what changed
  5. Applies fixes — updates API calls, adjusts config, handles deprecations
  6. Pushes new commits and re-runs CI
  7. Requests review when ready (or merges if policy allows)
  8. Escalates with context when it can't fix the issue

That last point matters more than I expected when I started working with this approach. Even when automation can't solve the problem, the difference between "tests failed" and "tests failed because lodash.get was removed in v5 — here's the migration guide and the 3 files that use it" saves 20 minutes of investigation. And those 20 minutes add up fast when you're staring at 40+ stale PRs.

What the Workflow Actually Looks Like

Let me walk through a realistic scenario.

Your React app depends on [email protected]. The React Query team released v5 back in October 2024 with breaking changes — renamed hooks, different caching behavior, new DevTools API. Renovate opens a PR to bump to v5.59.0.

CI fails. 12 tests red.

Without an agent, this PR sits. Maybe someone pins an "investigate" label on it. Maybe it stays open for 6 months until a junior dev gets assigned "tech debt cleanup" and spends a week on migrations.

With an agent:

Minute 0-2: Agent detects CI failure. Pulls the error logs. Sees useQuery signature mismatches.

Minute 2-5: Agent fetches the react-query v5 migration guide from TanStack's docs. Identifies the breaking changes: useQuery now takes an object instead of positional args. isLoading renamed to isPending.

Minute 5-15: Agent updates the 8 components that use useQuery. Changes useQuery(key, fetchFn, options) to useQuery({ queryKey: key, queryFn: fetchFn, ...options }). Updates isLoading references to isPending.

Minute 15-18: Agent commits changes. CI re-runs. 11 tests pass. 1 still fails — a flaky integration test that was already flaky.

Minute 18-19: Agent posts a comment: "Updated react-query to v5.59.0. Migration complete. One test failure appears unrelated (InventorySync.test.ts has been flaky since March — see issue #847)." Requests review from the frontend team.

Next morning: A human reviews the PR. The diff is clean. The agent's commit message explains what changed and why. The test that failed is a known flake. Merge.

Total human time: 5 minutes of review. Total elapsed time: overnight. Versus the alternative: 6 months in PR purgatory, then a 2-day migration sprint where someone (probably me, let's be honest) curses past-me for not just staying current. If you're dealing with flaky tests blocking PRs, there's a dedicated workflow for AI agents handling flaky test duty.

The Named-Tool Gap

Dependabot and Renovate are phenomenal at what they do. Snyk adds security context. GitHub Actions can auto-merge on green CI. But there's a gap in the middle — between "PR opened" and "PR ready to merge" — that none of these tools fill.

That gap is:

  • Investigation: Why did CI fail? What changed?
  • Remediation: Can we fix it automatically?
  • Context: If we can't fix it, what does the human need to know?
  • Follow-through: Did the fix work? Should we retry? Escalate?

This isn't a feature request for Dependabot. Investigating test failures and applying code fixes is a different category of work — the kind AI agents are actually good at in 2026.

Common Failures (And How Agents Handle Them)

Not every dependency update is fixable by automation. But most are more tractable than they seem.

Type signature changes: TypeScript updates often break type checks without breaking runtime behavior. Agents can read error messages, find the affected types, and update imports or type annotations. Success rate: high. (For analytics teams tracking these failures, correlating errors with funnel drop-offs helps prioritize which type breaks matter.)

Deprecated API calls: Agents read changelogs, identify deprecated functions, and apply the recommended replacements. Works well when the deprecation is documented. Fails when the library author just... deleted something without noting it. This happens more than you'd think. I've filed angry issues about it, and I'm not sorry.

Transitive dependency conflicts: The dreaded "peer dependency" error. Agents can parse the conflict, check for compatible version ranges, and adjust pinning. Sometimes requires manual judgment — but the agent can at least surface the exact conflict instead of dumping a wall of npm errors. (If you're running CI/CD pipelines with GitHub Actions, you'll see these conflicts surface fast.)

Breaking behavioral changes: The hardest category. When a library changes how it works (not just its API), tests might pass while the app behaves wrong. Agents can catch test failures but can't detect behavioral regressions without tests that cover them. This is where humans still matter.

Major version jumps with extensive migrations: React 17 to 18. Angular 14 to 15. Vue 2 to 3. These are multi-day projects, not automation targets. An agent should recognize a major version bump with hundreds of changelog entries and escalate immediately rather than attempting a fix. Don't let anyone tell you otherwise — some migrations just need a human with coffee and a whiteboard. (I tried to automate our Vue 2→3 migration once. It went poorly.)

Making It Work With Your Stack

The agent approach isn't tied to specific tools. You need:

  1. A dependency update bot — Renovate, Dependabot, or even manual PRs
  2. CI that runs on PRs — GitHub Actions, CircleCI, whatever
  3. An agent that can read CI output, modify code, and push commits

The third piece is where DevOS fits. The Developer agent (one of four built-in agents: Planner, Developer, QA, DevOps) takes tickets from your backlog — including "fix this failing PR" — reads context, makes code changes, runs tests, and requests review. It's designed to work inside your existing sprint workflow with AI agents, not as a separate system you have to babysit. (Teams scaling this approach should read our best practices for managing AI agents in sprints.)

For teams already using Linear or Jira, dependency updates become tickets. Agent picks them up from the backlog. Agent fixes them. Agent moves them to "Ready for Review." Human reviews. Merge. (We cover the mechanics in how to assign tickets to AI agents in a sprint board.)

The workflow looks like your normal sprint, except the dependency-update tickets get assigned to an agent instead of a human who'd rather be shipping features.

What About Security Updates?

Security patches deserve special handling. When Snyk or GitHub's security alerts flag a CVE, the priority changes.

An agent handling security updates should:

  • Prioritize critical and high-severity CVEs over routine updates
  • Fast-track patches that require no code changes (pure version bumps)
  • Escalate immediately when a security patch breaks tests — with the CVE details front and center
  • Never auto-merge security updates without human sign-off (or explicit policy approval)

The goal isn't to remove humans from security decisions. It's to surface those decisions faster, with better context, so a human can approve a clean patch in 30 seconds instead of ignoring it for a month because investigation seems hard. (Related: how QA agents handle code review covers the review side of this loop.) This same principle applies to compliance-heavy industries — TCPA consent rules require the same kind of fast, contextual human sign-off.

The Contrarian Take

Here's something not everyone agrees with: most teams should treat dependency updates like any other ticket.

The conventional wisdom is that dependency updates are "maintenance" — separate from feature work, handled during quiet periods, batched into quarterly cleanup sprints. I think this is wrong. This is how you end up 9 months behind with 43 stale PRs.

The alternative: dependency updates are tickets. They go in the backlog. They get prioritized (security patches high, patch bumps low). They get assigned. They get done.

If you assign them to humans, they'll always lose priority to feature work. Always. I've never seen a team where "update lodash" wins over "ship the checkout flow." If you have, please email me, I'd love to study your culture like an anthropologist.

If you assign them to agents, they get done in parallel — without competing for human attention. For teams new to this model, we've documented best practices for managing AI agents in sprints.

Frequently Asked Questions

Why do most Dependabot and Renovate PRs never get merged?

Because they break tests, require code changes, or pile up faster than any human can review. A PR that bumps lodash from 4.17.20 to 4.17.21 looks harmless — until it's one of 47 open dependency PRs and nobody has time to verify each one doesn't break something. The merge button is easy. The confidence to click it is hard.

Can AI agents actually fix breaking changes from dependency updates?

For most updates, yes. An agent can run the test suite, identify failures, read changelogs and migration guides, and apply the necessary code changes. Major version bumps with extensive API changes are harder — but those represent maybe 5% of dependency updates. The other 95% are patch and minor versions where the fix is usually straightforward.

How is this different from just enabling auto-merge on Renovate?

Auto-merge only works when tests pass. If a dependency update breaks something — even one test — auto-merge stops and the PR joins the pile. An agent goes further: it diagnoses the failure, attempts a fix, pushes a new commit, and re-runs CI. If the fix works, the PR can merge. If it doesn't, the agent escalates with context instead of leaving a red X forever.

What happens when the agent can't fix a breaking dependency update?

The agent should escalate with useful context — not just "tests failed." A good agent includes: which tests broke, what the error messages say, what it tried, and links to the relevant changelog entries. This turns a 30-minute investigation into a 5-minute decision. Even when automation can't solve the problem, it should make the human's job easier.


Join the DevOS Waitlist

AI agents that work as employees inside your sprints, standups, and tickets — not single-task copilots. Four built-in agents (Planner, Developer, QA, DevOps) pick up work from the backlog, ship in branches, request review. Free tier includes 2 agents and 50 dev tasks/month; Pro starts at $25/user/month with unlimited agents. Pre-launch — we're still building this thing.

Join the waitlist → · How agents-as-employees works

ai-agent-dependency-updatesrenovatedependabotpr-automationci-cdbuildinpublicsaasstudioaiworkforcebuildwithclaude