Your AI Agent Just Scaffolded a Project from 2020
When AI coding agents run npx without pinning versions, npm silently resolves old packages that are compatible with everything — including packages from 2020. Here's why it happens and how to stop it.
TL;DR: When AI coding agents run npx without pinning versions, npm silently installs old packages whose engines field is absent — treating “no constraint” as “compatible with everything.” This means agents scaffold projects from years ago, see success, and move on. The fix is version pinning in prompts and MCP server instructions.
Key takeaways:
- npm’s version resolution algorithm silently installs old packages when their
enginesfield excludes your Node version — even when newer versions exist- Packages with no
enginesfield win over packages with tight Node version constraints, because npm treats “no constraint” as “compatible with everything”- AI agents don’t catch this: they see exit code 0 and files appeared, not that the packages are 6 years old
- Pin versions in prompts (
[email protected]notcreate-next-app) and in MCP server instructions- The Vertical Agent Method’s spec-first approach prevents silent drift: verify the output, not just the exit code
Your AI agent just scaffolded a project from 2020.
It saw exit code 0. Files appeared. It moved on.
Nobody told it the packages were six years old.
This isn’t a bug in your agent. It’s a design decision in npm that trips up every AI coding assistant that runs npx without pinning a version — and it happens silently, without any warning in the terminal output.
The problem is bigger than npm. On Reddit’s r/node, developers are reporting agents that install packages which don’t exist anymore, run commands against wrong versions, and silently break production builds hours later. An agent that trusts exit code 0 will trust every exit code 0 — including the one where npm installed a package from 2020 because it was the only version compatible with your Node runtime.
How npm silently downgrades your packages
When you run npx create-some-app my-project without specifying a version, npm doesn’t install what’s tagged as latest. It installs the latest version compatible with your Node runtime.
This behavior shipped in npm-pick-manifest v9.1.0 (mid-2024). The resolution algorithm:
- Check the
latesttag — if it requires a Node version newer than yours, skip it - Check the next-highest version — same check
- Keep going until you find a version with no
enginesfield — npm treats “no constraint” as “compatible with everything” - Install that version
Here’s the concrete example from the Microsoft DevBlogs post. Given these package versions:
// v2.0.0 (latest)
{ "engines": { "node": ">=22.14.0 <23.0.0" } }
// v1.3.0 (old, no engines field)
{}
On Node 24: npm skips v2.0.0 (requires Node <23), skips v1.9.0 (same), and installs v1.3.0 — because v1.3.0 has no engine constraints, so npm considers it universally compatible.
The package with no engines field wins over the package that explicitly documents its Node version requirements.
Why humans catch this and agents don’t
| Human Developer | AI Agent |
|---|---|
| Might notice the version mismatch in the output | No context to detect the issue |
| Recognizes unfamiliar output as a red flag | Sees exit code 0, files appeared — done |
| Compares expected behavior vs. actual behavior | Trusts the tool completely |
| Reads terminal output and questions it | Takes results at face value |
A human developer scanning the scaffold output might notice “v1.11.0” and think “that seems old.” An AI agent sees “success” and continues to the next task.
In a real test, an agent running SPFx scaffolding on a Node version outside the supported range got v1.11.0 (July 2020) instead of the latest v1.23.0 — 12 versions and 6 years backwards. The agent knew v1.23.0 was the latest. But when npx resolved v1.11.0, it saw success and moved on.
The pattern is getting worse
More packages are adding engine constraints as a best practice — which means more packages will trigger this fallback behavior. An enterprise tool that certifies against Node 20 LTS will have "engines": { "node": ">=20 <21" }. On Node 22 or 24, that constraint fails, and npm falls back to the last version without engine constraints.
The irony: the packages doing the responsible thing (documenting their Node requirements) are the ones that get silently downgraded.
How to fix it
Pin versions in prompts
This is the single highest-leverage change you can make:
"Scaffold a project with [email protected]" ← correct
"Scaffold a Next.js project" ← version drift risk
Every AI coding agent that scaffolds projects should receive pinned versions. This applies to Cursor, Claude Code, Cline, and any MCP server that runs CLI tools.
Pin versions in your agent’s instructions
If you maintain MCP servers or instruction files for your agents, hardcode versions or make them required parameters:
# Instead of:
npx some-package
# Always generate:
npx [email protected]
Control your Node version
Use .nvmrc or .node-version files in your project root:
echo "22.14.0" > .nvmrc
fnm use --use-on-cd # auto-switch on cd
This ensures consistent Node versions across your team and CI — and reduces the chance of npm falling back to old packages because your local Node is newer than expected.
Verify output
After any scaffold command, check the generated package.json:
cat package.json | grep '"version"'
node --version # confirm Node version
If the versions don’t match what you expect, you caught the drift before it became a production problem.
The deeper lesson
Runtime environments are invisible to agents.
The agent sees your prompt, has access to tools, and runs commands. It doesn’t see your Node version, your .nvmrc file, or the engine constraints in a package’s package.json. It sees success when the exit code is 0.
This is why the Vertical Agent Method starts with a spec — a structured definition of what “done” looks like — and verifies output against it. An agent without a spec takes npm’s word for what “latest” means, and npm’s definition of “compatible” has nothing to do with your intent.
The fix isn’t a better model. It’s a better contract between you and the tools your agent runs.
FAQ
Why does npm silently install old package versions instead of the latest? Since npm-pick-manifest v9.1.0 (mid-2024), npm prioritizes packages whose “engines” field matches your Node version over the “latest” tag. If an old package has no “engines” field at all, npm considers it compatible with every Node version — so it gets selected over a newer package that explicitly requires Node 22+.
How do I know if my agent scaffolded an outdated project? Check the “engines” field in the generated package.json and compare it against your current Node version. If the project was generated without a pinned version (e.g., npx create-next-app instead of npx [email protected]), the package versions may be older than expected.
Does this affect all package ecosystems or just npm? This behavior is specific to npm’s resolution algorithm. Other package managers like pnpm and Yarn have different resolution strategies. The underlying principle — version constraints and compatibility fields — applies broadly, but the exact silent-downgrade behavior is npm-specific.
How do I prevent version drift when using AI coding agents? Always pin versions in your prompts: “Scaffold a project with [email protected]” not “Scaffold a Next.js project.” For MCP servers and instruction files, hardcode versions or make them required parameters. Use .nvmrc or .node-version files to enforce Node version consistency.
Related Posts
- How AI coding agents actually use your SDK — How agents discover and invoke tooling in production
- Best AI Coding Agents 2026 — A comparison of which coding agents handle CLI scaffolding best
- npm v12 breaking changes: what to know — Upcoming npm changes that affect how agents scaffold projects
This article was published on Agentic Up (https://agenticup.dev) — practical guides for developers and founders building with AI agents. Reach me at [email protected].