Skip to content
This repository has been archived by the owner on Mar 5, 2025. It is now read-only.

Error: Invalid number of arguments to Solidity function, when correct number of arguments is passed to a contract method #1043

Closed
smoove opened this issue Sep 15, 2017 · 30 comments

Comments

@smoove
Copy link

smoove commented Sep 15, 2017

I have this contract:

contract MyContract {
    function add(bytes32 _var1, string _var2, bytes32[] _var3) {
        // ...
    }
}

I call the method like this:

myContractInstance.add("a string", "another string", ["an", "array", "of", "strings"]);

Expected result: Transaction is successfull.
Actual result: "Error: Invalid number of arguments to Solidity function"

While debugging this, i tried adding another argument:

myContractInstance.add("a string", "another string", ["an", "array", "of", "strings"], "this argument does not exist in the declaration");

Expected result: "Error: Invalid number of arguments to Solidity function"
Actual result: Transaction is successfull.

This is the generated ABI:

{
  "constant": false,
  "inputs": [
    {
      "name": "_var1",
      "type": "bytes32"
    },
    {
      "name": "_var2",
      "type": "string"
    },
    {
      "name": "_var3",
      "type": "bytes32[]"
    }
  ],
  "name": "add",
  "outputs": [
    {
      "name": "owner",
      "type": "address"
    }
  ],
  "payable": false,
  "type": "function"
},

This exact code worked, before i upgraded web3 to the latest version.

@smoove
Copy link
Author

smoove commented Sep 15, 2017

Possibly related to: #925

@frozeman
Copy link
Contributor

It expects a callback, and for send transaction an object as last parameter.
I tested it against the 1.0 branch and its working.

Can please retest, also you are sending strings and not valid bytes as parameters, so there is a type mismatch between your input and your ABI

@smoove
Copy link
Author

smoove commented Sep 19, 2017

@frozeman You mean like this?

myContractInstance.add("a string", "another string", ["an", "array", "of", "strings"], {from: ...}).then(...); ?

I do that in my real code, i just cut that out for brevity.

Regarding the type mismatch: Well, it worked before, i assumed web3 (or truffle / truffle-contract) would handle type conversion internally.

@frozeman
Copy link
Contributor

I dont know what truffle adds or changed on the contract object...
i will have a test locally with the 0.20.0

@frozeman
Copy link
Contributor

I tested locally and doesnt give me this parameter error, so it seems that this is related to truffle. @tcoulter any idea?

@tcoulter
Copy link

Might be us. I'll take a look!

@smoove
Copy link
Author

smoove commented Sep 21, 2017

@tcoulter Little update:

The problem seems to only occur inside truffles migration files.

I use migrations to add some data to the development chain for testing purposes.

As mentioned above, i can get the migrations to run by adding the additional argument.

Running my tests does not require the additional argument.

This is a simplified version of my "data loading" migration file:

var MyContract = artifacts.require("./MyContract.sol");

module.exports = function(deployer) {
    return deployer.then(function() {
        return MyContract.deployed().then((instance) => {
            instance.add("a string", "another string", ["an", "array", "of", "strings"], {from: ...});
        });
    });
}

Am i using migrations wrong?

@tcoulter
Copy link

Sounds like it's interpreting the last parameter, an array, as an object, and then assuming it's the tx params object. Thanks for this. Will get on it right now.

@smoove
Copy link
Author

smoove commented Sep 21, 2017

Thanks gents, closing this issue.

@smoove smoove closed this as completed Sep 21, 2017
@tcoulter
Copy link

Alright, update on this. It all comes back to #995; instanceof Array, which #995 replaces, doesn't correctly test for arrays in some situations. The built version of Truffle exposes one of those cases with web3 v0.20.1.

Fortunately, web3 v0.20.2 fixes the issue. We'll upgrade Truffle to use v0.20.2 and put out a new release Monday.

@tcoulter
Copy link

Truffle v3.4.11 is out, upgrading web3 to v0.20.2. Thanks all!

@yozgatsi
Copy link

web3 is at 0.20.1 in latest beta, is this intentional? when will it be upgraded?
Truffle v4.0.0-beta.2 (core: 4.0.0-beta.2)
Solidity v0.4.17 (solc-js)
less ~/.nvm/versions/node/v8.4.0/lib/node_modules/truffle/package.json
"_from": "truffle@beta",
"_id": "[email protected]",
...
"web3": "^0.20.1",
...

@cyberience
Copy link

Guys, Delete your build folder, then run the command.

npm run truffle migrate --reset --compile-all

I find it works best when running truffle locally to the folder rather than globally, due to the beta and different versions getting updated quickly recently.
if you prefer the global approach try

truffle migrate --reset --compile-all

@Hu4F00d
Copy link

Hu4F00d commented Nov 28, 2017

I keep having to delete the build folder to make things work. I was having a different problem where trying to read simple info from my smart contracts would throw a Big Number error. Deleting the build folder solved it again. Doesn't feel optimal :P

@k26dr
Copy link

k26dr commented Dec 23, 2017

I get this error occasionally with Truffle. Deleting the build folder and re-compiling fixes the error every time.

jasonrhaas added a commit to jasonrhaas/web that referenced this issue Jan 5, 2018
To potentially resolve some issues like this one:
web3/web3.js#1043
@kyriediculous
Copy link

kyriediculous commented Mar 22, 2018

Still getting this error even after recompilng everyting.
Most recent truffle version and web3 0.20.6

My solution was to use the contract object inside the truffleContract instance and call the functions from there.

@jonashaag
Copy link
Contributor

Just got this too, reason was a type mismatch (I gave a Date while a uint was expected). Poor error handling!

@beether
Copy link

beether commented Mar 27, 2018

Guys, this is an API that nearly EVERY Ethereum developer will end up using. Errors like this should be embarrassing. This error is awful and wastes so much time for every developer.

Please give SENSIBLE ERRORS about inputs. If one is expected and not provided, vice versa, or type mismatch.

Next, allow calling methods in a sensible way. None of this ordinal arguments MESS.

Eg, for myMethod(uint _val1, string _val2) allow calls like myContract.myMethod({_val1: 123, _val2: "foo"} , {...opts...})

Or: myContract.myMethod([val1, val2], {..opts..}) if ABI doesn't have names.

Using ordinality in arguments is always a mess. You have to type check, and it's annoying to reflectively call things via fn.call and fn.apply. And you get crazy results when a user passes, say, an object instead of a number... now it's going to parse it as the opts array and give a nonsense error. Plus, if you allow calling functions as defined above, you can actually give a USEFUL error that, for example _val2 was expected to be a string.

I made an issue about both of these, separately, about a year ago, and have seen this error cited in COUNTLESS places ALL OVER THE PLACE. Nobody cares about the syntax sugar of doing myContract.myMethod(val1, val2) vs myContract.myMethod([val1, val2]). It is quite frankly an awful design decision. So many downsides to it and no upside at all other than not having to type [ and ].

@k26dr
Copy link

k26dr commented Mar 27, 2018

@beether It's open source software. You're free to contribute

@beether
Copy link

beether commented Mar 29, 2018

@kyriediculous It's web3. It's what comes with every browser extension that supports Ethereum. Kind of hard to just not use it.

@k26dr The fact that something is open source doesn't magically absolve the creators, who I'm pretty sure were compensated by the Ethererum Foundation, from implementing sensible design decisions. Furthermore, you might as well go and post your comment to every single "Issue" in all of GitHub.

@h36yang
Copy link

h36yang commented Apr 1, 2018

I get this issue too, with the following latest stable truffle and web3 versions:

  • truffle: 4.1.5
  • truffle-contract: 3.0.4
  • web3: 0.20.6

Uncaught (in promise) Error: Invalid number of arguments to Solidity function

I see this issue is closed, but don't seem to be able to find a solution for this. Can anyone please help? I'm still new to blockchain development :(

@koirikivi
Copy link

koirikivi commented Apr 2, 2018

@h36yang and whomever else it may concern, I got this same issue when working with 0x.js. What was strange was that the error only happened in the production (= minified) js build, not with the development (= unminified) JS build!

Well, turns out that this piece of code in web3's utils/utils.js:

var isBigNumber = function (object) {
    return object instanceof BigNumber ||
        (object && object.constructor && object.constructor.name === 'BigNumber');
};

is used to validate arguments of type BigNumber, and if any of those arguments doesn't pass the check, it results in the Uncaught (in promise) Error: Invalid number of arguments to Solidity function error.

However, the isinstance check didn't return true, because web3 uses the forked https://github.com/frozeman/bignumber.js-nolookahead version of BigNumber.js which is not used elsewhere in our code. What also happened with our production build was that the name BigNumber was optimized to Y, and as such, the constructor name check didn't return true either!

I don't know if this relevant for your situation, but I'm just posting this here in case it helps someone else.

Anyway, I think it would be better to do the isBigNumber check some other way. There's even a function in the latest BigNumber.js library called drumroll BigNumber.isBigNumber that could probably be used. However, this doesn't appear to be included in the version of BigNumber.js (https://github.com/frozeman/bignumber.js-nolookahead) used by web3.

Edit: There's already a submitted issue for this: #1356 . I posted my temporary fix in the issue.

@beether
Copy link

beether commented Apr 3, 2018

@koirikivi This bug has been around forever, kudos for digging into it -- I remember doing that months ago. I've found the most reliable workaround is to always use the web3's version of BigNumber:

const BigNumber = web3.toBigNumber(0).constructor

BTW, can you imagine how much time it could have saved you if it gave an error like argument 'foo' expected to be a number or BigNumber, instead got: ....

@koirikivi
Copy link

@beether Thanks for the tip!

I agree on the point about the error messages. The "wrong number of arguments" line is confusing since that's not what's actually happening in this case. A minimal change, even without breaking the current API, would be to throw something like expected argument N to be Array or BigNumber, was XXX instead of just filtering the wrongly-typed parameters away.

@AlvaroLuken
Copy link

Deleting build folders and truffle migrate --reset --compile-all does not work for me! :( Can't test!!

@dshafe
Copy link

dshafe commented Apr 26, 2018

This happened to me too: Basically the error should read "Incorrect data types". My contract was expecting numbers and got strings so a quick Number("string) fix solved the issue.

@bitcoinwarrior1
Copy link

Hi all, I am getting this issue too but using the contract object directly instead of the truffle object i.e. web3.eth.Contract(abi, address). This is only broken now after I updated to ^1.0.0-beta.36 from an early pre beta version (0.18.4). Any ideas?

@dcsan
Copy link

dcsan commented Oct 27, 2019

Basically the error should read "Incorrect data types". My contract was expecting numbers and got strings so a quick Number("string) fix solved the issue.

so basically this error which has 100s of thousands of instances in google, is actually just a mistaken message? it is about argument types not number of args?

@cgewecke
Copy link
Collaborator

@dcsan The majority of these reports were caused by compilation bug in Truffle 4, although there are a handful of other possible causes. But this thread has been quiet for a while...

What context are you seeing it in?

@dmadindividual
Copy link

this is 2023 and i still have this error

Web3ContractError: The number of arguments is not matching the methods required number. You need to pass 0 arguments.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests