How to Fix Hardhat Test Errors
In this tutorial, you'll learn about How to Fix Hardhat Test Errors. We cover key concepts, practical examples, and best practices.
The Problem
Your Hardhat tests fail with HH1: You are using a version of ethers that is not compatible, TimeoutError: operation timed out, or TypeError: contract.deployed is not a function. Tests that should pass are failing due to configuration or API changes.
Quick Fix
Fix 1: ethers.js Version Mismatch
WRONG — using ethers v6 syntax with hardhat-ethers v5:
const { ethers } = require("hardhat");
async function deployFixture() {
const Contract = await ethers.getContractFactory("MyContract");
const contract = await Contract.deploy(); // ethers v5
await contract.deployed(); // ethers v5 — WRONG for hardhat-ethers v6
}
// TypeError: contract.deployed is not a function
RIGHT — match the version:
// For hardhat-ethers v6 (Hardhat 2.19+, ethers v6):
const { ethers } = require("hardhat");
async function deployFixture() {
const Contract = await ethers.getContractFactory("MyContract");
const contract = await Contract.deploy(); // returns a contract directly
// No need for .deployed() — the transaction is already mined
return { contract };
}
Fix 2: Chai Matchers Not Loaded
WRONG — using expect(..).to.be.revertedWithout without the plugin:
// hardhat.config.js — missing @nomicfoundation/hardhat-chai-matchers
await expect(contract.fail()).to.be.revertedWith("error");
// TypeError: expect(...).to.be.revertedWith is not a function
RIGHT — install and configure:
npm install --save-dev @nomicfoundation/hardhat-chai-matchers
// hardhat.config.js:
require("@nomicfoundation/hardhat-chai-matchers");
// Now use in tests:
await expect(contract.fail()).to.be.revertedWith("error");
await expect(contract.fail()).to.be.revertedWithoutReason();
Fix 3: Test Timeout
WRONG — default Mocha timeout (2000ms) not enough for blockchain tests:
describe("MyContract", function () {
it("should mint 1000 tokens", async function () {
// (times out if the test takes > 2000ms)
});
});
RIGHT — increase the timeout:
describe("MyContract", function () {
this.timeout(60000); // 60 seconds for all tests in this block
it("should mint 1000 tokens", async function () {
// (now has 60 seconds)
}).timeout(30000); // or per-test timeout
});
In Hardhat config:
// hardhat.config.js:
module.exports = {
mocha: {
timeout: 60000,
},
};
Fix 4: Network Not Forked
// Using mainnet fork without configuring:
const dai = await ethers.getContractAt("IERC20", "0x6B175474E89094C44Da98b954EedeAC495271d0F");
const balance = await dai.balanceOf("0x...");
// Error: could not decode result (the fork is not configured)
RIGHT — enable forking in config:
// hardhat.config.js:
module.exports = {
networks: {
hardhat: {
forking: {
url: "https://eth-mainnet.g.alchemy.com/v2/YOUR_KEY",
blockNumber: 19000000, // optional: pin to a block
},
},
},
};
Fix 5: Hardhat Network Not Started
npx hardhat test
# Error: HH8: There's one or more errors in your config file:
# (the Hardhat node is not running)
RIGHT — let Hardhat manage the node automatically:
# `npx hardhat test` starts an ephemeral Hardhat Network node automatically.
# No need to start a separate node.
# For console: npx hardhat console --network localhost
# (requires `npx hardhat node` in another terminal)
Fix 6: Snapshot Isolation
// Tests that modify state affect subsequent tests:
it("test 1", async () => {
await contract.setState(42);
});
it("test 2", async () => {
// state is still 42 from test 1 — tests are not isolated
});
RIGHT — use fixtures for isolation:
async function deployFixture() {
const [owner] = await ethers.getSigners();
const Contract = await ethers.getContractFactory("MyContract");
const contract = await Contract.deploy();
return { contract, owner };
}
it("test 1", async () => {
const { contract } = await loadFixture(deployFixture);
await contract.setState(42);
});
it("test 2", async () => {
const { contract } = await loadFixture(deployFixture);
// contract starts fresh — state is default
});
Use DodaTech's Test Suite Optimizer to analyze test performance, parallelize where possible, and reduce CI pipeline runtimes.
Prevention
- Match hardhat-ethers version with ethers.js version.
- Install
hardhat-chai-matchersfor revert assertions. - Increase Mocha timeout for blockchain tests.
- Use
loadFixturefor state isolation between tests. - Run
npx hardhat test --parallelfor faster execution.
Common Mistakes with test error
- Non-exhaustive pattern matches that compile with warnings then crash at runtime
- Misunderstanding that
Stringis[Char]with poor performance for large text operations - Using
foldlinstead offoldl'causing stack overflow on large lists
These mistakes appear frequently in real-world HARDHAT code. DodaTech's contributors have identified these patterns through analysis of open-source projects and production systems.
Practice Exercise
Write a pure function that safely divides two integers using Maybe, then test it with edge cases like division by zero and negative numbers.
This exercise reinforces the concepts covered in this guide. Try implementing it before checking online solutions.
FAQ
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro