question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

ERC721: unable to access token with ownerOf, getting "owner query for nonexistent token"

See original GitHub issue

Issue

Getting Error: Returned error: VM Exception while processing transaction: revert ERC721: owner query for nonexistent token while trying to use the ownerOf function, which means that the ID used for ownerOf is wrong but it doesn’t make any sense.

Steps to reproduce

  1. Create a project using Truffle, OpenZeppelin
truffle init
npm init
npm install @openzeppelin/contracts
  1. Edit truffle-config.js to use latest version of Solidity:
  compilers: {
    solc: {
      version: "0.8.3",    // Fetch exact version from solc-bin (default: truffle's version)
      // docker: true,        // Use "0.5.1" you've installed locally with docker (default: false)
      // settings: {          // See the solidity docs for advice about optimization and evmVersion
      //  optimizer: {
      //    enabled: false,
      //    runs: 200
      //  },
      //  evmVersion: "byzantium"
      // }
    }
  },
  1. Create contracts/GameItem.sol according to OpenZeppelin documentation on ERC721
// contracts/GameItem.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol";
import "@openzeppelin/contracts/utils/Counters.sol";

contract GameItem is ERC721URIStorage {
    using Counters for Counters.Counter;
    Counters.Counter private _tokenIds;

    constructor() ERC721("GameItem", "ITM") {}

    function awardItem(address player, string memory tokenURI)
        public
        returns (uint256)
    {
        _tokenIds.increment();

        uint256 newItemId = _tokenIds.current();
        _mint(player, newItemId);
        _setTokenURI(newItemId, tokenURI);

        return newItemId;
    }
}
  1. Create migrations/2_deploy_contracts.js
const GameItem = artifacts.require("GameItem")

module.exports = function (deployer) {
    deployer.deploy(GameItem)
}
  1. Create tests/GameItem.test.js the purpose of which is to mint a token and find its owner
const GameItem = artifacts.require("GameItem")

contract("GameItem", (accounts) => {
    before(async() => {
        gameItem = await GameItem.deployed()
    })

    it("Minting", async() => {
        gameItem.awardItem(accounts[0], "meta")
        let result = await gameItem.ownerOf(1)
        console.log(result)
    })
})
  1. Run truffle test and get the following:
Contract: GameItem
    1) Minting

    Events emitted during test:
    ---------------------------

    IERC721.Transfer(
      from: <indexed> 0x0000000000000000000000000000000000000000 (type: address),
      to: <indexed> 0x627306090abaB3A6e1400e9345bC60c78a8BEf57 (type: address),
      tokenId: <indexed> 1 (type: uint256)
    )


    ---------------------------


  0 passing (1s)
  1 failing

  1) Contract: GameItem
       Minting:
     Error: Returned error: VM Exception while processing transaction: revert ERC721: owner query for nonexistent token
      at Context.<anonymous> (test/GameItem.test.js:11:37)
      at processTicksAndRejections (internal/process/task_queues.js:95:5)

What I think is happening

For some reason, 1 is an incorrect ID, even though when I transfer a token by that ID, it doesn’t throw an exception. (I used transferFrom(), if token with ID 1 wouldn’t exist it would throw an exception since it requires _isApprovedOrOwner, and _isApprovedOrOwner requires _exists. But it worked well until I decided to check the owner by ID.)

What I tried to do

  1. Doing the same in development mode
truffle development
migrate
gameItem = await GameItem.deployed()
gameItem.awardItem(accounts[0], "meta")
gameItem.ownerOf(1)

Works as intended, returns an address, no exceptions.

  1. Then I thought: maybe the ID is actually different, not 1. So I decided to take control of it instead of using awardItem from docs. I added the following function to GameItem.sol:
function mintWrapper(address player, uint256 tokenId)
        public
    {
        _mint(player, tokenId);
    }

And used that function in the GameItem.test.js:

    it("Minting", async() => {
        // gameItem.awardItem(accounts[0], "meta")
        gameItem.mintWrapper(accounts[0], 1)
        let result = await gameItem.ownerOf(1)
        console.log(result)
    }

So now I control the ID of the token, I specified it to be 1, and yet gameItem.ownerOf(1) throws an exception.

Environment

  • OS: macOS

  • Truffle version: v5.4.9

  • Solidity version: 0.8.3

  • Node.js version: v14.17.1

  • web3.js version: v1.5.2

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Comments:6 (2 by maintainers)

github_iconTop GitHub Comments

2reactions
ohaponiukcommented, Sep 17, 2021

I forgot to run Ganache 😅 That’s it

0reactions
Amxxcommented, Sep 17, 2021

You can await without putting the result in a variable

Read more comments on GitHub >

github_iconTop Results From Across the Web

ERC721: operator query for nonexistent token #3302 - GitHub
After deploy ERC-721 Contract, when I am trying to use transferFrom in createMarketItem function it's showing ERC721: operator query for ...
Read more >
Getting error Erc721 : operator Query for non existent token
The error is thrown by the OpenZeppelin _isApprovedOrOwner() function when the token ID is not minted. There's no function to mint a token...
Read more >
`ERC721: operator query for nonexistent token` - Contracts
I have been working on a project. Following is the NFT contract on ERC721 as parent: // SPDX-License-Identifier: MIT pragma solidity ^0.8.4; ...
Read more >
NFT implementation of OpenZeppelin ERC721 ownerOf ...
However, when I try to verify the owner of the token in tests I always get "ERC721: owner query for nonexistent token".
Read more >
"ERC721 owner query for nonexistent token" error for ... - Reddit
You're asking for the owner of a token that doesn't exist. Maybe an address in your list doesn't have a token.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found