SHIP · Jun 12, 2026

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.

Agent-ready: drop this post into Claude Code or Codex

TL;DR: My AI agent scaffolded a project with packages from 2020. Not because the packages were good. Because npm resolves to the oldest compatible version when nothing is pinned.

When AI coding agents run npx without pinning versions, npm silently installs old packages. Here is why npm prefers old packages and how to pin versions in your prompts.

Key takeaways:

  • npm’s version resolution algorithm silently installs old packages when their engines field excludes your Node version: even when newer versions exist
  • Packages with no engines field 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 (create-next-app@15.3 not create-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:

  1. Check the latest tag: if it requires a Node version newer than yours, skip it
  2. Check the next-highest version: same check
  3. Keep going until you find a version with no engines field: npm treats “no constraint” as “compatible with everything”
  4. 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 DeveloperAI Agent
Might notice the version mismatch in the outputNo context to detect the issue
Recognizes unfamiliar output as a red flagSees exit code 0, files appeared: done
Compares expected behavior vs. actual behaviorTrusts the tool completely
Reads terminal output and questions itTakes 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.

Why is the silent version drift pattern 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-use change you can make:

"Scaffold a project with create-next-app@15.3" ← 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 some-package@1.5.0

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.

What is the deeper lesson from silent version drift?

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 create-next-app@15.3), 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 create-next-app@15.3” 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.

Stack Overflow discussion on upstream dependency conflicts covers npm’s resolution behavior and version pinning strategies.


This article was published on Agentic Up (https://agenticup.dev): practical guides for developers and founders building with AI agents. Reach me at hello@agenticup.dev.

Newsletter

Get the brief on AI agents

Practical posts on shipping agents, automating work, and building in public. No hype, no fluff.

Contact: hello@agenticup.dev