ethereum/go-ethereum · error · Error
Cannot send value to non-payable function
Error message
Cannot send value to non-payable function
What it means
SolidityFunction.sendTransaction refuses to send a transaction whose payload.value > 0 when the ABI entry for the method was not marked payable (this._payable false). It is a client-side guard against a transaction the EVM would revert anyway, checked before anything is broadcast.
Source
Thrown at internal/jsre/deps/web3.js:4157
error = e;
}
callback(error, unpacked);
});
};
/**
* Should be used to sendTransaction to solidity function
*
* @method sendTransaction
*/
SolidityFunction.prototype.sendTransaction = function () {
var args = Array.prototype.slice.call(arguments).filter(function (a) {return a !== undefined; });
var callback = this.extractCallback(args);
var payload = this.toPayload(args);
if (payload.value > 0 && !this._payable) {
throw new Error('Cannot send value to non-payable function');
}
if (!callback) {
return this._eth.sendTransaction(payload);
}
this._eth.sendTransaction(payload, callback);
};
/**
* Should be used to estimateGas of solidity function
*
* @method estimateGas
*/
SolidityFunction.prototype.estimateGas = function () {
var args = Array.prototype.slice.call(arguments);
var callback = this.extractCallback(args);
var payload = this.toPayload(args);View on GitHub (pinned to 6bb0588ad8)
Solutions
- Remove the value field from the transaction options if the function must not receive ether.
- If the function should accept ether, mark it payable in Solidity (function foo() payable) and redeploy.
- Regenerate/refresh the ABI passed to web3 so it matches the deployed contract.
- For plain ether transfer use address.sendTransaction or eth.sendTransaction instead of a contract method.
Example fix
// before
instance.buy({from: acct, value: web3.toWei(1, 'ether')}); // ABI not payable
// after
// Solidity: function buy() public payable
instance.buy({from: acct, value: web3.toWei(1, 'ether')}); Defensive patterns
Strategy: validation
Validate before calling
function callMethod(instance, name, opts) {
var abi = instance.abi.filter(function (a) { return a.name === name; })[0];
if (opts && opts.value > 0 && !abi.payable) {
throw new Error(name + ' is not payable; remove value or mark payable in Solidity');
}
return instance[name](opts);
} Type guard
function isPayableMethod(instance, name) {
return instance.abi.some(function (a) { return a.name === name && a.payable; });
} Try / catch
try { instance.buy({from: a, value: v}); }
catch (e) {
if (/non-payable function/.test(e.message)) { /* drop value or redeploy payable */ }
} Prevention
- Check the ABI's payable flag before attaching value to options.
- Keep the ABI artifact in sync with the deployed Solidity version.
When it happens
Trigger: Calling instance.method.sendTransaction({from, value: web3.toWei(1,'ether'), gas}) or the sugar instance.method(..., {value: X}) where the ABI for method lacks 'payable': true. Filtering undefined args then building the payload leaves value > 0 and _payable false, so it throws.
Common situations: ABI from an older Solidity version (<0.4.x) where payable is not encoded for fallback, deploying with one ABI artifact and calling with another, or simply forgetting the function is non-payable when testing value transfers.
Related errors
- This unit doesn't exists, please use the one of the followin
- Contract transaction couldn't be found after 50 blocks
- The contract code couldn't be stored, please check your gas
- Cannot send value to non-payable constructor
- Filter ID Error: filter().get() can't be chained synchronous
AI-assisted analysis of ethereum/go-ethereum@6bb0588ad8 (2026-08-15).
Data as JSON: /api/errors/c2e07b0d45c9db61.
Report an issue: GitHub.