Skip to content
ecdsa.com
ethers v6 (JavaScript)Web3 wallets and signatures

Error message

ambiguous primary types or unused types: "EIP712Domain", "Mail"

Also printed as

  • ambiguous primary types or unused types

The listed names are your unreferenced types. `err.message` adds the full `types` value and the ethers version; `err.code` is `INVALID_ARGUMENT`.

ethers v6 (JavaScript) — TypedDataEncoder used by signTypedData / verifyTypedData

What it means

ethers infers the primary type of EIP-712 typed data as the single type that no other type references. In your `types` object several types are unreferenced, so it cannot tell which one is being signed — and in practice the extra one is almost always `EIP712Domain`. ethers builds the domain type itself from the `domain` argument and must not receive it in `types`, while the `eth_signTypedData_v4` JSON format (MetaMask, WalletConnect) includes it.

Why it happens

How to fix it

  1. 1.

    Remove EIP712Domain before calling ethers

    Destructure it away; the signature is identical to the one a wallet produces for the v4 payload, because the domain type is derived from the same fields.

    js
    const { EIP712Domain, ...types } = typedData.types; // ethers derives the domain type itself
    const signature = await signer.signTypedData(typedData.domain, types, typedData.message);
    const signer2 = verifyTypedData(typedData.domain, types, typedData.message, signature);
  2. 2.

    Check the inferred primary type

    `TypedDataEncoder.from(types).primaryType` throws the same error or returns the type ethers will hash — a quick check in tests.

    js
    import { TypedDataEncoder } from "ethers";
    
    // Inspect what ethers considers the primary type before signing.
    console.log(TypedDataEncoder.from(types).primaryType);

Related errors

Browse the full signature error database