Skip to content

How to Fix Hardhat Test Errors

DodaTech Updated 2026-06-24 4 min read

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-matchers for revert assertions.
  • Increase Mocha timeout for blockchain tests.
  • Use loadFixture for state isolation between tests.
  • Run npx hardhat test --parallel for faster execution.

Common Mistakes with test error

  1. Non-exhaustive pattern matches that compile with warnings then crash at runtime
  2. Misunderstanding that String is [Char] with poor performance for large text operations
  3. Using foldl instead of foldl' 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

### Why does Hardhat say "HH1: You are using a version of ethers that is not compatible"?

Hardhat 2.19+ includes hardhat-ethers v6 which requires ethers v6. Either downgrade Hardhat or upgrade your test code to ethers v6 syntax (no .deployed(), use ethers.parseEther instead of ethers.utils.parseEther).

How do I test a specific revert reason?

Use await expect(contract.fail()).to.be.revertedWith("error message") with the hardhat-chai-matchers plugin. For non-reverting failures, use to.be.revertedWithoutReason() or to.be.revertedWithCustomError(contract, "CustomError").

Can I debug Hardhat tests with console.log?

Yes, use Hardhat's built-in console.log in your Solidity contract: import "hardhat/console.sol";. The output appears in the test runner output. This works only on Hardhat Network, not on forked mainnet.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro