ethereum/go-ethereum · error · Error
Cannot send value to non-payable constructor
Error message
Cannot send value to non-payable constructor
What it means
Filter.get() supports both sync and async styles. In synchronous mode it reads this.filterId; if the filter has not been created yet (filterId === null, creation is asynchronous), it cannot chain synchronously and throws this error telling you to pass a callback. The filter id only exists after the async creation round-trip completes.
Source
Thrown at internal/jsre/deps/web3.js:2988
var callback;
var args = Array.prototype.slice.call(arguments);
if (utils.isFunction(args[args.length - 1])) {
callback = args.pop();
}
var last = args[args.length - 1];
if (utils.isObject(last) && !utils.isArray(last)) {
options = args.pop();
}
if (options.value > 0) {
var constructorAbi = abi.filter(function (json) {
return json.type === 'constructor' && json.inputs.length === args.length;
})[0] || {};
if (!constructorAbi.payable) {
throw new Error('Cannot send value to non-payable constructor');
}
}
var bytes = encodeConstructorParams(this.abi, args);
options.data += bytes;
if (callback) {
// wait for the contract address and check if the code was deployed
this.eth.sendTransaction(options, function (err, hash) {
if (err) {
callback(err);
} else {
// add the transaction hash
contract.transactionHash = hash;
// call callback for the first time
callback(null, contract);View on GitHub (pinned to 6bb0588ad8)
Solutions
- Use the callback form: f.get(function(err, logs) { ... }).
- Or wait for filter creation to finish before calling get() synchronously.
- For one-shot history, prefer eth.getPastLogs / getLogs-style APIs which are callback/Promise based.
Example fix
// before
var f = eth.filter({fromBlock: 0, toBlock: 'latest'});
var logs = f.get(); // throws when filterId is null
// after
var f = eth.filter({fromBlock: 0, toBlock: 'latest'});
f.get(function (err, logs) { console.log(logs); }); Defensive patterns
Strategy: validation
Validate before calling
function getFilterLogsSync(f) {
if (f.filterId === null || f.filterId === undefined) {
throw new Error('filter not yet created; use f.get(callback)');
}
return f.get();
} Type guard
function isFilterReady(f) { return f && f.filterId !== null && f.filterId !== undefined; } Prevention
- Prefer the callback form of get() in console and scripts.
- Treat filter creation as async; never chain get() immediately after eth.filter().
When it happens
Trigger: Calling web3.eth.filter({...}).get() immediately in the console (or without new) so get() runs before the filter creation callback has assigned filterId. Typical in the geth console one-liner: var f = eth.filter('latest'); f.get(); fired too early.
Common situations: Interactive geth console usage where the user expects synchronous semantics, or scripts that ignore the async nature of filter creation in the bundled web3 version.
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
- Filter ID Error: filter().get() can't be chained synchronous
- Cannot send value to non-payable function
AI-assisted analysis of ethereum/go-ethereum@6bb0588ad8 (2026-08-15).
Data as JSON: /api/errors/ae2602759be2590f.
Report an issue: GitHub.