DEV Community

hefty
hefty

Posted on

An AI-Suggested Package Is Not an Install Command

A coding agent suggests a package that sounds exactly right for the job. Then it wants to run npm install. Hold on: a package name in a response is a proposal, not permission to change your dependency tree.

In a small npm-focused experiment, a DEV.to author gave three AI coding tools 30 everyday tasks and counted six suggestions for nonexistent packages, counted per tool. Two invented names recurred across tools. The author also found two real packages that were very new or little-used. No failed lookup was installed. Those observations are a reason to add a check, not a measured attack rate, a model ranking, or proof that an unfamiliar package is malicious.

Three different questions get collapsed into one

First: does the exact package name exist in the registry this project will use? Check the full name, including scope. If the proposed name is missing, don't let the agent quietly pick a lookalike and continue.

Second: is this the dependency you want? Inspect the intended version, publisher or maintainer information, provenance you can actually verify, and whether the package does the specific job requested. A registry entry answers the existence question. It doesn't answer the trust question. A new package may be perfectly legitimate; its unfamiliarity calls for review, not an automatic accusation.

Third: what would installation change? The proposed command, manifest edit, lockfile delta, and verification results are separate artifacts. A lockfile shows which dependencies changed; it does not certify that the resulting tree is safe.

If you only check the first question, you've built a spelling check and called it a security boundary.

Put the gate where the action happens

Wove's README describes a useful pattern for file edits: its tooling can enforce read-before-edit and limit large-file rewrites. Those are file-operation controls described by the project, not a claim that Wove audits npm packages or blocks installs.

Enforce the rule at the tool that performs the action. You can put "verify packages first" in the prompt, but an unrestricted command runner can still install them. File-edit restrictions alone won't stop a package-manager process. The install gate belongs at the process/tool boundary as well.

Here is a proposed workflow for a JavaScript task, not a feature test of any agent:

  1. The agent submits the exact package name, requested version, and why the task needs it. It does not run the install yet.
  2. The gate checks that name and version against the registry configured for this project. A missing entry stops the request. An unexpected substitute becomes a new proposal, not a silent retry.
  3. A reviewer checks publisher/version context and task fit. Uncertain provenance pauses for a decision; the gate does not pretend that metadata alone settles trust.
  4. Only after approval does the command runner receive authority for the reviewed install. Record the actual command and the package/lockfile changes it produced.
  5. Run the project's relevant checks and attach their results to the dependency change. If a check was skipped, say so.

That last step is easy to miss. Approval for one name and version isn't blanket approval for a different version chosen later or for a second package the agent decides to add. Reopen the gate when the proposal changes.

Advice about tools has a provenance problem too

A Hacker News discussion about a proposed shared memory for agent tool reviews immediately raised questions about seeded reviews and vendor gaming. That is community concern, not evidence of a package attack or proof that the proposed review system is compromised. Still, it is a good reminder not to let an agent's recommendation, or a glowing review it found, stand in for the checks above.

Let the agent propose a dependency. Ask for the exact package, reason, and expected change. Check those details before the runner gets permission to install it. A plausible sentence should never be the thing that authorizes a new dependency.


Source notes

Top comments (0)