← All news
dependency-hygiene5 min read

Your AI assistant shipped without a lockfile (again)

By Seaworthy · 26 October 2026

Gray steel chain and padlock securing a metal gate

Photo by John Salvino on Unsplash

Your AI assistant shipped without a lockfile (again)

I keep seeing the same repo pattern, and it makes me wince every time. Someone asks an AI coding assistant to add a library, the assistant cheerfully edits package.json (or requirements.txt, or Cargo.toml), maybe runs a snippet, and calls it done. No lockfile change. Or the lockfile is there but eight months stale. Or there is no lockfile at all because the project was scaffolded by a model that never thought about reproducibility.

This is not a small blemish. A lockfile is the record of the exact dependency graph you tested against. Skip it and you are asking every CI run, every teammate, and every machine to resolve a slightly different set of packages. Sometimes those resolutions agree. Sometimes one of them pulls a brand-new transitive release that nobody reviewed.

The irony is that AI assistants are great at the part of dependency work that feels tedious (editing manifests, suggesting versions, writing install commands) and bad at the habit that actually protects you. They optimize for "the code compiles." They do not default to "the build is reproducible." That is your job, and it takes less time than people think.

Three flavors of the same mistake

Missing entirely. A fresh project has a manifest and no lockfile. The assistant adds three packages, runs tests, and reports success. Future installs are a different lottery every time.

Stale. The lockfile exists but was last updated before the assistant touched anything. The manifest now lists a new dependency that the lockfile has never heard of. Depending on your tool, installs either silently resolve it fresh or fail in confusing ways. Neither outcome is good.

Ignored. The lockfile is committed but the assistant, or a helpful snippet, tells you to add it to .gitignore. I have seen this advice in generated README text. Do not take dependency advice from a model that has not read your workflow.

What the bad pattern looks like

Here is a typical diff after an assistant adds a dependency. Notice what is absent.

# package.json
 "dependencies": {
   "express": "^4.18.0",
+  "some-parser": "^2.3.1"
 }

# no change to package-lock.json
# no change to yarn.lock
# no change to pnpm-lock.yaml

And the equally common .gitignore crime:

node_modules/
package-lock.json   # this line is a bug, not hygiene

What the fix looks like

The fix is boring, which is the point. After any assistant-driven dependency edit, regenerate the lockfile and commit it in the same change. For a JavaScript project with npm:

# after editing package.json
npm install --package-lock-only
npm ci                        # verify the lockfile actually resolves cleanly
git add package.json package-lock.json
git commit -m "add some-parser and refresh lockfile"

npm ci is the part people skip. It refuses to run when the manifest and lockfile disagree, which is exactly the failure you want to catch locally instead of in CI. The same idea applies elsewhere: pip-compile or uv lock for Python, cargo update --workspace or a plain cargo build for Rust, bundle lock for Ruby, go mod tidy for Go. The command differs; the rule does not.

If you want the assistant to help, give it an explicit instruction in your project rules. Something like: "Any change to a dependency manifest must be accompanied by a regenerated lockfile in the same commit. Run the package manager's install-verify command before reporting done." That single line catches a startling number of misses.

Why this keeps happening

Most assistants are trained on a lot of code and a little operational discipline. Lockfiles are large, noisy, and machine-generated, so they rarely appear in tutorial snippets. The model learns the manifest edit and not the follow-up. It is not being malicious. It is reflecting the distribution of examples it saw, and most examples stop at npm install.

You can compensate in two places. First, automate the check: a CI step that runs npm ci (or the equivalent) fails the build on a mismatch, no human memory required. Second, make the local loop cheap enough that nobody skips it. A pre-commit hook that runs npm install --package-lock-only and stages the result takes a few seconds and removes the entire class of error.

The opinion part

I think stale lockfiles are the most underrated supply-chain issue in AI-assisted development. They are not dramatic. No CVE announcement follows them. But they quietly widen the gap between what you reviewed and what actually installs, and that gap is where unpleasant surprises live. The teams I worry about are not the ones with elaborate security reviews. They are the ones moving fast with a helpful model and a manifest that says one thing while the build says another.

Treat a missing lockfile update the same way you would treat a failing test. It is not a stylistic preference. It is a correctness problem wearing casual clothes.

If you want a second set of eyes on this class of gap, Seaworthy reviews dependency hygiene across the projects your team ships.

This article was generated by AI and summarises publicly available sources.

From the makers of Seaworthy

Seaworthy scans your repo for the issues covered in articles like this one.

Security gaps, exposed secrets, and misconfigurations — caught before you deploy. Free to run, no account needed.

$ npx seaworthycode