Your AI Pair Programmer Has Terrible Taste in Dependencies

  • Konrad Madej
  • AI
  • 18 Jul, 2026
  • 07 Mins read

In October 2025, someone committed 47 AI-generated “agent skills” to a popular GitHub repository of shared assistant configurations. One of them told coding agents to run a package called react-codeshift. That package did not exist. An LLM had invented the name, a plausible mash-up of two real tools, jscodeshift and react-codemod. The skill spread through forks and copies, and by the time a researcher at Aikido noticed, the phantom package was referenced in 237 repositories. He registered the name defensively before an attacker could. It has been quietly collecting downloads every day since: not from curious humans, but from AI agents executing the install command their configuration told them to run.

Nothing malicious happened, this time, because the person who got there first was friendly. But sit with the mechanics for a moment. A machine invented a dependency, other machines propagated it, and still other machines installed it. At no point in that chain did anyone ask the question a senior engineer asks by reflex: is this library real, maintained, and worth trusting?

I’ve written before about how dependency updates became a security paradox. This article is about the newer half of the problem: what happens when the entity choosing your dependencies is a language model, and what to do about it.

The model is not choosing. It is remembering.

Let me be precise about the mechanism, because it explains every failure mode that follows.

When an LLM suggests a library, it is not evaluating the ecosystem. It is reproducing statistical patterns from training data that is, at best, months old, and dominated by whatever was popular when it was written. There’s no lookup, no freshness check, no concept that a library has a maintainer who might have quit last year.

The bias this produces is measurable and stark. A 2025 study of eight major models found that across hundreds of programming tasks, each model drew on only 32 to 39 distinct libraries, out of more than 7,000 available Python packages. NumPy showed up in 45% of solutions, including tasks that didn’t need it. Meanwhile Polars, growing twice as fast as pandas at the time, appeared exactly zero times, and FastAPI showed up in only 9% of web-server answers while models reached for older stacks instead.

So the assistant’s taste in libraries is roughly: whatever was dominant two years ago, forever. Matt Asay put the endgame bluntly in his InfoWorld piece on the feedback loop: popular frameworks generate more training data, which makes models recommend them more, which makes them more popular. His thought experiment stays with me: if ChatGPT had existed before Kubernetes, would Kubernetes ever have happened?

Sometimes the library does not exist at all

The taste problem has a sharper edge: a meaningful fraction of the packages LLMs recommend are fictional.

The definitive study, presented at USENIX Security 2025, generated 576,000 code samples across 16 models and checked every package reference. 19.7% pointed at packages that don’t exist: 205,474 unique invented names. Commercial models did better (around 5% for the GPT series) and open models worse (over 20% on average), but nobody was clean.

The finding that turns this from a quality bug into a security problem is repeatability. When the researchers re-ran hallucination-inducing prompts ten times, 43% of the fake names came back in every single run. Hallucinations aren’t random noise; they’re stable properties of the model. Which means an attacker doesn’t need to guess what an LLM might invent. They can ask it, collect the answers, and register the names on npm or PyPI before you do. Seth Larson of the Python Software Foundation coined the term for this: slopsquatting.

The proof-of-concept came early. Security researcher Bar Lanyado noticed models kept hallucinating a package called huggingface-cli, registered it as an empty placeholder, and watched it collect over 30,000 downloads in three months, including references from repositories of large companies. By 2026 this stopped being theoretical: ReversingLabs documented the PromptMink campaign, attributed to a North Korean group, which published malicious npm packages with README files engineered to look authoritative specifically to AI agents. A real hackathon project ingested one of the malicious SDKs in a commit co-authored by a coding agent. And this month, researchers generalized the attack beyond packages: assistants hallucinate GitHub repository and skill names so consistently (up to 85% of repository requests produced the same wrong name) that registering the phantom repos works too.

When the library is real, the version is often sick

Suppose the package exists. The next question is which version the model pins, and here the data is genuinely worse than I expected.

A large 2026 measurement study across ten models found that in 37 to 56 percent of coding tasks, the LLM specified at least one library version with a known CVE, most rated critical or high. The detail that matters: between 72 and 91 percent of those CVEs were disclosed before the model’s training cutoff. This is not the familiar “the model doesn’t know about last month’s patch” problem. The models learned the vulnerable pins from training data, because that’s what the internet’s example code contains, and all ten models converged on the same risky releases. Switching vendors doesn’t help.

The same pattern shows up one level down, at the API surface: an ICSE 2025 study found every model tested routinely completed code with deprecated APIs across major Python libraries. And it extends to the update path itself: Sonatype’s 2026 report found that when asked to recommend dependency upgrades without live registry data, GPT-5 hallucinated 27.8% of the component versions it suggested, occasionally recommending actual malware.

All of this lands on an ecosystem that was already sick

Here’s the part that connects to the “poorly maintained” half of the problem, and it would be a serious issue even if LLMs recommended perfectly.

Sonatype’s analysis of 1.2 million open source projects found only about 11% actively maintained. Tidelift’s maintainer survey puts a human face on the number: 60% of maintainers are unpaid volunteers, and 60% have quit or considered quitting. The ecosystem your assistant recommends from is mostly abandonware, tended by exhausted volunteers.

LLMs amplify this in both directions at once. They funnel enormous new usage into a frozen top-40 of libraries, chosen for past popularity rather than current health, and some of those are exactly the tired, single-maintainer projects that attackers now target through phishing and account takeover. Simultaneously they starve everything newer: a library released after the training cutoff effectively doesn’t exist, no matter how much better it is. The old map gets more traffic; the new roads get none.

And the volume makes this structural rather than anecdotal. Ninety percent of software professionals now use AI daily. Microsoft and Google say somewhere between a quarter and a third of their new code is AI-written. Industry research suggests developers accept roughly 39% of AI-generated code without revision, and Veracode has now measured for two years running that about 45% of AI-generated code fails basic security tests, a figure that has not improved with newer models. Dependency choice rides along inside all of that unreviewed volume.

What actually works

The tempting response is a policy memo telling developers to “review AI suggestions carefully.” The Stanford user study already told us how that ends: people with AI assistants wrote less secure code while being more confident it was secure. The workable defenses don’t rely on vigilance. Five things, roughly in order of effort:

Ground the model in current reality. The USENIX researchers measured that retrieval-augmented generation cut hallucinations by 24 to 49 percent, and this is the mechanism behind docs-grounding tools like the Context7 MCP server, which feed version-specific, current documentation into the assistant’s context. I’ll be honest about the evidence: nobody has independently measured Context7’s effect, but the underlying RAG result is solid, and in my own use, grounding an agent in real docs visibly reduces invented APIs. Vulnerability-context servers (Endor Labs ships one) do the same for CVE awareness.

Write your dependency policy where the model can read it. Every serious assistant now reads repo-level instruction files: CLAUDE.md, .cursorrules, copilot-instructions.md. Most teams use them for style preferences. Use them for dependencies: here is the approved list for this repo, prefer these libraries for these jobs, and never add a new dependency without flagging it for human review. It’s not a hard control (models can ignore instructions), but it moves the default, and the default is where most of the volume is.

Verify existence and health before anything gets installed. This is the reflex the react-codeshift chain was missing, and it automates well. A pre-install gate should ask: does this package exist, how old is it, what do its download numbers and maintenance signals look like? OpenSSF Scorecard and deps.dev expose exactly this data via free APIs, and commercial tools (Socket, Snyk, Endor Labs) now ship checks aimed specifically at AI-suggested dependencies. A package that appeared on the registry three weeks ago with no history should not enter your build because an agent felt confident about it.

Put a registry between the agent and the internet. A private proxy with quarantine for first-seen packages, plus the cooldown policies I covered in the previous article, counters slopsquatting almost incidentally: an attacker who registers a hallucinated name today still has to get through the aging window and quarantine checks before any of your builds can pull it. If you already built cooldown infrastructure for the supply-chain reasons, you’ve built most of the anti-slopsquatting defense too.

Keep a human on the dependency decision. In April 2026, CISA and its international partners published their first joint guidance on agentic AI, and one recommendation stands out for how specific it is: don’t let agents install dependencies autonomously, without developer review. I’d implement it in code review: a diff that adds a dependency is a different kind of diff, and your tooling should surface it that way (a changed lockfile line buried in a 400-line AI-generated PR is where phantom packages live). Adding a library is an architectural decision with a ten-year tail. It was never a good thing to do on autopilot; we just got away with it when the autopilot was slower.

When this doesn’t apply

For throwaway code, prototypes, and one-off scripts, most of this machinery is overkill; if the code never reaches a pipeline with credentials, a hallucinated package is an ImportError, not an incident. And none of this is an argument against coding assistants, which I use daily and happily. The argument is narrower: dependency selection is the one part of code generation where the model’s knowledge is structurally stale and the failure mode is an attacker-controlled foothold, so it’s the part that deserves guardrails first.

Where this leaves us

An LLM is a colleague who has read everything ever written about your city but hasn’t been outside in two years. Ask it about street layout and architecture, and it’s brilliant. Ask it which restaurants are open tonight, and it will answer with the same confidence, from a map where half the kitchens have closed and a few of the addresses never existed.

Library choice is a restaurant question. The ecosystem moves, maintainers quit, packages rot, and the model’s map cannot know. So let the assistant write the code; it’s good at that. But the taste (which libraries deserve a place in a system you’ll maintain for a decade) is still your job. Check that the kitchen is open, and who’s cooking, before you order.

Related posts

Lessons from Real-World Enterprise Chatbot Projects

Lessons from Real-World Enterprise Chatbot Projects

As I work with teams deploying chatbots in enterprise settings, I've noticed a recurring pattern: people consistently underestimate what's involved. They see the chat interface — a text box, some resp

read more
Dependabot Says Update Now. Supply-Chain Attacks Say Slow Down.

Dependabot Says Update Now. Supply-Chain Attacks Say Slow Down.

On September 8, 2025, someone phished the maintainer of chalk and debug, two of the most downloaded packages on npm. The malicious versions were live for about two hours before they were pulled. In th

read more