The code looks perfect. The import sits at the top of the file like it has always belonged there, the method call reads exactly like the library's real API, and the whole thing is written with total confidence. Then you run it, and the truth lands: that package does not exist. That method was never real. The AI invented an entire dependency and called it like an old friend.
This is one of the strangest failure modes in vibe coding, and one of the most dangerous — because the failure is sometimes louder than a crash, and sometimes much quieter.
Why AI hallucinates dependencies
An LLM does not look up whether a library exists. It predicts the most plausible next tokens given everything it has seen. Most of the time that plausibility lines up with reality, because real, popular packages dominate its training data. But plausibility and existence are not the same thing, and the gaps show up as confident fiction: an invented package whose name sounds exactly like it should exist, a hallucinated method on a real library because it fits the pattern of the library's other functions, a reference to a file that was never created, or an outdated API called the way it worked in a version the library has long since moved past.
The unifying thread is that the AI cannot tell its memory of code from real code. A name that should exist is statistically indistinguishable, to the model, from one that does. And this is not a problem you can skim-review away — hallucinated code reads exactly like real code, which is what makes it hallucination and not a typo.
The quiet version is the one that should scare you. Attackers noticed that LLMs invent the same plausible-sounding names over and over, so they publish real malicious packages under those invented names and wait. This is slopsquatting: squatting on the hallucinations. When your AI imports a package that does not exist and someone has registered that exact name, your install does not error — it pulls down hostile code and runs it inside your app. The hallucination became a supply-chain attack, and nothing turned red.
How afterclick catches invented code
afterclick is a governance platform for AI-built software. Several of its capabilities aim straight at hallucinated dependencies, and together they close both the loud failure and the quiet one.
Verification is built into the loop — a change is not done until it runs. afterclick treats "the AI wrote it" and "it works" as two different states. A change is not finished on the strength of plausible-looking code; it is finished only when it has actually been run and observed. A hallucinated import or a method that does not exist fails that step immediately and never gets to masquerade as done. The crash that would have hit you in production happens in the loop instead, where it is cheap and nobody is watching.
The independent second-eye engine reviews dependency and import changes for intent. When a change adds or alters dependencies, afterclick's engine reviews it as a separate reviewer that did not write the code — and a newly introduced package, an unfamiliar import, or a name that does not match anything you already depend on is exactly the kind of thing it surfaces. It is not running a linter; it is asking whether this dependency is what you actually meant to pull in. That is precisely where slopsquatting lives: a new package name nobody vetted. The concern is advisory by default, you keep owner override, and you can switch on enforce so a suspicious dependency cannot ship until it is cleared.
The audit trail and read-only dashboard record what got pulled in and why. Every dependency change, every review, and every ship lands in a human-readable record on a dashboard you can scroll back through. So when a new package shows up, there is a written answer to "where did this come from, who added it, was it reviewed?" — instead of a mystery import discovered months later. A real vet and no vet stop looking identical after the fact.
Cross-session memory keeps a list of what you already trust. afterclick remembers, across sessions, the dependencies your project actually uses and the decisions behind them. So when a fresh agent — yours or a teammate's — reaches for a package, the project has a memory of what is genuinely in play, instead of every session re-guessing from scratch and inventing a brand-new name for something you already had.
In practice it looks like this: your agent confidently adds an import for a data-validation library that sounds completely standard. afterclick's verification step runs the change and it fails — the package was never published. On the next attempt the agent reaches for a real-sounding lookalike that someone has quietly registered; the second-eye engine flags it as a brand-new dependency nobody on the project has vetted, the install pauses under enforce, and the audit trail records the whole exchange. The hallucination that would have become a breach is now a line item you cleared in seconds.
| Aspect | Without afterclick | With afterclick |
|---|---|---|
| Invented package that crashes | Found in production | Fails verification in the loop, never done |
| Slopsquatted malicious lookalike | Installs silently, runs hostile code | Flagged as an unvetted new dependency before install |
| Method that does not exist | Reads fine on review, breaks later | Run-it-to-prove-it before done |
| Where a dependency came from | Lost in scrolled-away chat | Recorded in the audit trail |
| What you already trust | Re-guessed every session | Held in cross-session memory |
Trust what runs, not what reads well — start free
Confident code that does not exist is the cleanest illusion AI produces. It reads better than the real thing, right up until you run it. The fix is to stop trusting the read, start requiring the run, and put an independent set of eyes on what your dependencies are quietly pulling in.
That is the whole job afterclick does. It is free to start and installs with one paste — no rebuild of your stack, advisory by default so it never gets in your way until you want it to. Claude is the developer. afterclick is everyone else — including the reviewer who checks that the library you just imported is actually real. Wire it in before your next install, and let the made-up dependency die in the loop instead of in production.
