# How do I stop an AI coding agent from installing hallucinated packages (slopsquatting)?

**Short answer:** Don't let the agent run npm install or pip install on its own. Make package installs ask you first, and check each new name before approving: does it exist on the registry, when was it first published, who maintains it, and does it link to a real source repo? A name that doesn't exist is a hallucination. A name that exists but is days old with no history may be a squat of one. Then limit the damage: set npm's min-release-age so brand-new versions aren't installed, turn off install scripts by default, and commit a lockfile. Research on 576,000 generated code samples found 19.7% of the packages they referenced did not exist (arXiv 2406.10279), and the same fake names often come back, which is what attackers count on.

## Checklist
1. Make dependency installs need your approval. In Claude Code, add ask rules such as Bash(npm install *), Bash(pnpm add *) and Bash(pip install *). Deny and ask rules match even inside chained commands and subshells.
2. For every new name the agent proposes, look it up yourself: npm view <name> (a 404 means it doesn't exist) or https://pypi.org/pypi/<name>/json.
3. If it exists, check time.created, the maintainers, the repository link, recent downloads and whether the docs the agent cited actually mention it. A days-old package with a plausible name and no history is a red flag.
4. Prefer a well-known package that does the same job over one you can't vouch for, even if the agent's code calls the unknown one.
5. Set min-release-age in .npmrc (for example 7 days) so npm only installs versions that have been public that long.
6. Turn off install scripts: ignore-scripts=true in .npmrc, or use npm's allowScripts policy in package.json so only packages you approve run install-time scripts.
7. Commit the lockfile and install with npm ci in CI, so a later run can't quietly pick up a new package.
8. Check the license of each new dependency before you ship, not after.

## What slopsquatting is
- LLMs sometimes write code that imports a package that doesn't exist. If someone registers that name with malicious code, the next developer or agent who runs the suggested install gets it. Seth Larson (PSF Security Developer-in-Residence) coined the term slopsquatting for this, and Andrew Nesbitt popularised it in April 2025.
- The largest study so far (Spracklen et al., USENIX Security 2025, arXiv 2406.10279) tested 16 code models on 576,000 Python and JavaScript samples. Of 2.23 million package references, 440,445 (19.7%) were hallucinated, covering 205,474 unique names. Commercial models averaged 5.2% and open-source models 21.7%, and the best (GPT-4 Turbo) was 3.59%.
- Repeats are the risk. When the authors re-ran prompts ten times, 43% of hallucinated names appeared in all ten runs and 58% appeared more than once, so an attacker can predict which names to register. Only 13.4% were within one or two characters of a real package, so these aren't just typos that a typo-squatting check would catch.
- The paper notes that checking a name against a list of existing packages stops working once an attacker has registered it. 'It exists' is not the same as 'it's the package the agent meant'.

## Settings that make installs safer
- npm min-release-age: if set, npm only installs versions that were available more than the given number of days ago. min-release-age-exclude lets your own scope update immediately. A brand-new squat of a hallucinated name won't install until the window passes, which gives registries and scanners time to catch it.
- npm ignore-scripts: when true, npm doesn't run scripts from package.json files during install. Recent npm also has an allowScripts policy in package.json (and npm approve-scripts) to allow install scripts only for packages you've approved.
- Claude Code permission rules are checked deny, then ask, then allow, and an ask rule like Bash(npm install *) still prompts for that command inside a chain such as cd x && npm install y. Use ask, not allow, for install commands.
- None of this tells you whether a package is malicious. It gives you a pause in which to look, and limits what runs before you do.

## What can go wrong?
- The agent adds the dependency to package.json or requirements.txt and a later CI run installs it. Review dependency-file diffs too, not just install commands.
- The agent 'fixes' an import error by installing whatever name the error suggests. Stop and check that name the same way.
- A hallucinated Python name is installed from npm or the other way around. The study found 8.7% of hallucinated Python package names were real npm packages.
- Approving installs on autopilot. If you approve every prompt, the ask rule does nothing.

## Ask Rightshold (free, no key)
Add the MCP server https://www.rightshold.com/mcp to Claude, Cursor, ChatGPT, Grok or VS Code (one-click setup: https://www.rightshold.com/start?ref=seo), then ask: "Before I install it, what license does the npm package this agent wants to add declare, and is it OK for a commercial app?"

```json
{
  "tool": "check_license",
  "arguments": {
    "source_url": "https://www.npmjs.com/package/express",
    "intended_use": {
      "commercial_use": true
    }
  }
}
```
- Free, no key. Reads the license the npm or PyPI page declares and checks it for your use. If the registry has no such package (or can't be read just then), the answer is needs_review with license_not_determined, which is your cue to check whether the name exists.
- Whole project, free: curl -fsSL https://www.rightshold.com/check.mjs | node - lists every dependency with its license, and flags any with no license found.
- check_rights_batch checks up to 100 items in one call.

_Rightshold checks the license a registry page declares. It doesn't check whether a package is malicious, scan its code, or verify that it's the package your agent meant. Use it alongside the steps above, not instead of them._

## Sources
- [Spracklen et al., We Have a Package for You! A Comprehensive Analysis of Package Hallucinations by Code Generating LLMs (arXiv 2406.10279, USENIX Security 2025)](https://arxiv.org/abs/2406.10279)
- [Simon Willison: A quote from Andrew Nesbitt on slopsquatting (April 2025)](https://simonwillison.net/2025/Apr/12/andrew-nesbitt/)
- [Andrew Nesbitt: Slopsquatting meets Dependency Confusion](https://nesbitt.io/2025/12/10/slopsquatting-meets-dependency-confusion.html)
- [npm docs: config (min-release-age, ignore-scripts, allow-scripts)](https://docs.npmjs.com/cli/v11/using-npm/config)
- [npm docs: npm view](https://docs.npmjs.com/cli/v11/commands/npm-view)
- [PyPI docs: JSON API](https://docs.pypi.org/api/json/)
- [Claude Code docs: Configure permissions (ask rules, rule order)](https://code.claude.com/docs/en/permissions)

## Related
- [How to check every npm dependency's license before shipping](https://www.rightshold.com/answers/how-to-check-licenses-of-all-npm-dependencies-before-shipping)
- [How to keep .env secrets and API keys away from an AI coding agent](https://www.rightshold.com/answers/how-to-keep-env-secrets-and-api-keys-away-from-ai-coding-agents)
- [How to restrict which sites an AI coding agent can reach](https://www.rightshold.com/answers/how-to-restrict-network-egress-for-ai-coding-agents)
- [How to vet a VS Code, Cursor or Open VSX extension before installing it](https://www.rightshold.com/answers/how-to-vet-a-vs-code-extension-before-installing-it)

_Not legal advice. Updated 2026-10-30. JSON: https://www.rightshold.com/answers/how-to-stop-an-ai-coding-agent-from-installing-hallucinated-packages-slopsquatting.json_