A coding agent will sometimes invent a method, use an outdated API or claim that tests pass (see Hallucinations). Do not take its word for it. Two habits deal with this: make it read before it writes, and give it a check it can run, so it catches its own mistakes before you do.

When to use it

On every change you plan to keep. It matters most when the agent works on its own for a while, touches libraries that change often, or adds dependencies.

How to do it

Make it read instead of guess

  1. Point it at the sources first. “Before changing anything, read src/auth/ and package.json, and check which version of zod we use.”
  2. Allow “I don’t know”. “If you are not sure an API exists, check the types in node_modules or the docs. Do not make it up.”
  3. Use the docs that ship with your code. Type declarations in node_modules (.d.ts files) show the real signatures of the version you have installed. The agent can open them like any other file.
  4. Fetch current docs when needed. Claude Code’s WebFetch tool fetches a URL, such as the official docs page for your library version. An MCP server such as Context7 pulls version-specific documentation and code examples into the session.

Give it a check it can run

  1. Type-check. npx tsc --noEmit runs the TypeScript compiler as a checker only, without writing output files. Most invented methods and fields fail here immediately, which is why TypeScript and agents work so well together.
  2. Write the failing test first. With vitest or jest, ask for a test that reproduces the bug, watch it fail, then fix the code until it passes.
  3. Lint. Run eslint as part of the same check.
  4. Run the real thing. For a backend, curl the endpoint. For a frontend, let the agent open the page: Claude in Chrome lets Claude Code open your local app, try a form, read console errors and fix what it finds.
  5. Make it a standing rule. Put it in CLAUDE.md, for example “After every change, run npm run typecheck && npm test.”
  6. Ask for evidence, not claims. Do not accept “everything works” without the command and its output. Reviewing the output is faster than re-running it yourself.
  7. Review new dependencies by eye before npm install: check that the package exists, is the one you meant, and is maintained. Invented package names are a real attack vector (slopsquatting).

Example

A package.json script the agent can run in one go:

{
  "scripts": {
    "typecheck": "tsc --noEmit",
    "lint": "eslint .",
    "test": "vitest run",
    "check": "npm run typecheck && npm run lint && npm test"
  }
}

And the line in CLAUDE.md:

## Verification
- After every change, run `npm run check` and show the output before saying it works.
- Never add a dependency without showing me the package name first.

With that in place, when the agent writes await fs.promises.exists(path), the type-check fails, the agent reads the error, opens the Node types and switches to fs.promises.access, all before you look at the diff.

Common mistakes

  • Trusting “tests pass” without output. Ask to see the run.
  • No check at all. Without something that returns pass or fail, the agent stops when the code looks done, and you become the test suite.
  • Letting the agent install packages unreviewed. That removes the one point where a fake package gets caught.
  • Asking from memory about fast-moving libraries. Point it at the installed version or the current docs instead.

Citations

  1. Best practices for Claude Code: give Claude a way to verify its work
  2. Tools reference: WebFetch
  3. Use Claude Code with Chrome
  4. TypeScript: noEmit
  5. Context7 repository
  6. We Have a Package for You! A Comprehensive Analysis of Package Hallucinations by Code Generating LLMs (USENIX Security 2025)