Slopsquatting: The Hallucinated Package Problem in AI Code

SprintX Team

Written By

SprintX Team

AI & Product Engineering

July 29, 2026

6 min read

A hallucinated dependency name being registered by an attacker

AI models invent package names; attackers register them and wait. Here is the mechanics of the attack, how to find hallucinated dependencies, and how to prevent them.

Typosquatting has been around forever: register a package name one keystroke away from a popular one and wait for fat fingers. It works, but slowly, and only on the humans who mistype.

Slopsquatting is the version that scales. Language models do not mistype — they confabulate. Ask for a library that does a specific thing and a model will sometimes produce a plausible, well-named, entirely fictional package, with a confident import statement and usage example to match. The Cloud Security Alliance found that roughly 19.7% of 2.23 million AI-generated code samples referenced package names that do not exist.

Here is the part that turns a curiosity into an attack: models hallucinate the same names repeatedly. An attacker does not have to guess. They can prompt the popular models a few thousand times, collect the fictional names that come back more than once, and register them.

How the attack works

The chain is short, which is what makes it effective.

  1. Harvest. Run a model across a large set of realistic coding prompts and log every package it imports that does not resolve in the registry.
  2. Filter. Keep the names that recur. Recurrence means the next developer asking a similar question gets the same suggestion.
  3. Register. Publish a package under that exact name. Registries are open by design; nobody has to approve it.
  4. Wait. Somewhere, a developer or an autonomous agent asks the same question, receives the same import, and runs the install command.
  5. Execute. In many ecosystems, installation alone runs code — npm lifecycle scripts, Python setup logic. The payload does not need your app to call the library. It runs on install, on a developer machine or in CI, with whatever credentials that environment holds.

Step five is where people underestimate the blast radius. A CI runner holds deployment credentials, registry tokens, and cloud access — a far better target than the application itself.

Why models invent package names

Three causes, and they compound.

Naming is predictable. Package names follow strong conventions. A model that has seen thousands of names in the form of a framework prefix plus a function suffix will generate new ones in the same shape, and they will sound correct because they follow the same rules the real ones do.

The registry is not consulted. Unless the tool has been wired to check, generation happens without any lookup. There is no step where the model verifies that the thing it just named exists.

Deprecation reads as existence. Packages that were renamed, merged, or deleted after training still appear throughout the training data. The model has genuinely seen them; they are simply no longer there — which leaves a name that is unclaimed and reputable-looking. That combination is exactly what an attacker wants.

Agentic coding sharpens all of this. When a coding agent installs its own dependencies mid-session to fix its own import error, nobody sees the package name at all. It appears in a lockfile, and lockfiles are the file everyone skips in review.

Finding hallucinated dependencies in code you already have

Do this on any AI-built project that has been running for a while. It takes under an hour.

Diff installed against declared. Compare what is in your lockfile to what your manifest declares and to what your source actually imports. Three-way mismatches are where the interesting stuff hides.

Look up every direct dependency by hand. For each one, check that the registry page exists, that it has a repository link, and that the repository is real. This is boring and it is the entire detection method — a package that resolves is not the same as a package that is legitimate.

Sort by publish date and download count. A recently published dependency with very few downloads, sitting in an agent-built project, deserves an explanation. Real packages have history and obvious provenance.

Read the install scripts. Any postinstall or preinstall hook needs justification. Native modules legitimately have them; a date-formatting helper does not.

SignalWhat it usually meansWhat to do
Package not found on installPure hallucination, not yet weaponizedRemove the import, find the real library
Exists, published within weeks, near-zero downloadsPossible slopsquatDo not install; verify the repository and maintainer
Exists, no source repository linkedUnverifiable provenanceTreat as untrusted, replace
Has postinstall script, no native codeHigh riskBlock, install with scripts disabled, inspect
In lockfile, not in manifest or importsAgent added it, nobody kept itRemove and rebuild the lockfile

If a suspicious package was ever installed on a machine with credentials, treat it as a credential incident, not a dependency cleanup. Rotate everything that machine could reach. The broader cleanup process is covered in auditing dependencies in an AI-written codebase.

Prevention that survives agentic coding

Telling developers to check every suggestion does not work, because the agent installs packages without showing anyone. The controls have to sit in the pipeline.

  • Commit the lockfile and install from it. Use the reproducible install command in CI so builds cannot silently pull something new.
  • Disable install scripts by default. Both npm and pip support installing without running lifecycle hooks. Allow them for the small set of packages that genuinely need native builds, and only those.
  • Put a proxy or private registry in front of the public one. This gives you an allowlist, a quarantine period for newly published packages, and a record of exactly what entered your build.
  • Fail CI on new direct dependencies. Not on all changes — just on additions to the direct dependency list, which should be a human decision. Pair this with the review gates in a CI/CD setup for a vibe-coded app.
  • Never install from AI output on a machine with production credentials. Do it in a container with no ambient access. Developer laptops are the softest target in most companies.

The intent behind all of this is one rule: adding a dependency should be a deliberate act by a person, even when a machine wrote the code that needs it.

Frequently asked questions

Does this only affect npm and PyPI? Those are the loudest cases because both registries are open, both are heavily represented in training data, and both can execute code at install time. The same mechanism applies anywhere name-based resolution meets open publishing — Go modules, crates, Ruby gems, container image tags. Ecosystems that require signed publishing or reserve namespaces are harder to attack, not immune.

If the install failed with a 404, am I fine? For now. A failed install means the name was hallucinated but not yet registered, which is a temporary state. Note the name, remove the import, and do not retry the install later on the assumption that it was a network blip.

Can I just ask the model to verify its own package suggestions? Only if the tool actually performs a registry lookup — some agents now do, and that genuinely helps. A model asked to confirm from memory will confirm, confidently, including for packages that have never existed. Verification has to touch the registry, and that check belongs in your pipeline, not in a prompt. It is one of the standard checks in an AI code audit.


If your project was built by an agent that installed its own dependencies, nobody has read that list, and it deploys from CI with real credentials, that is a supply chain exposure with a clear fix. SprintX audits AI-generated dependency trees, verifies provenance package by package, and puts the controls in your pipeline so it stops happening. Send us your lockfile.

Related Articles

Contact us

to find out how this model can streamline your business!