Skip to content

Error: missing revert data (action="estimateGas", data=null, reason=null) #5026

@AlirezaEthDev

Description

@AlirezaEthDev

Ethers Version

6.4.0

Describe the Problem

I'm developing a Nodejs bot called app.js. The bot is a concurrent app that does two tasks simultaneously. Task A is listening to events of some contracts. Task B is executing checkLoans() functions. But whenever function liqDetect() called by checkLoans() the below error thrown:

Error: missing revert data (action="estimateGas", data=null, reason=null, transaction={ "data": "0x574f93cb00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000060978c9c8fd998b7997ae854ad8cef8fb9b8a698f99d09e5f368b6ccf92be99bda930c9c9fd582b1090ae834ad8cef8fb0b7a037f21d09e5f368b6ccf11be99bda930c9c9fd582b1090ae834ad8cef8fb0b7a037f21d09e5f368b6ccf11be99bda", "from": "0x1164E83a5313089422e0ef4428dE07520c746D79", "to": "0x8C2025e8d92c7411b6eb450FF886022f38b07487" }, invocation=null, revert=null, code=CALL_EXCEPTION, version=6.15.0)

The bot runs on Sonic mainnet. What is the problem and what does data=null refer to?

app.js:

/*_____________________ import modules _____________________________*/
import { ethers, NonceManager } from 'ethers';
import { createClient } from 'redis';
import fs from 'fs';
import cron from 'node-cron';
import path from 'path';
import { pathToFileURL } from 'url';
import { eventOf } from './utils/getEvent.js';
import dotenv from 'dotenv'

const outbound = fs.writeFileSync;
dotenv.config();

/*_____________________ set Redis client ___________________________*/

// Instantiate Redis client
const redisClient = createClient({
  socket: {
    host: '127.0.0.1',
    port: 6379
  },
  password: process.env.REDIS_PASS
});

await redisClient.connect();
console.info(`\u{1F50C} Redis connected!`);

/*___________________________ constants ____________________________*/
const SONIC_WS = process.env.SONIC_WS;
const LOCAL = process.env.LOCAL_ENDPOINT;
const ADMIN_KEY = process.env.ADMIN_1_KEY;
const MODERATOR_KEY = process.env.MODERATOR_2_KEY;
const DIAMOND = process.env.DIAMOND;
const loanMgmtJson = './contracts/facets/lending/LoanManagment.sol/LoanManagement.json';
const loanEndJson = './contracts/utils/LoanEnd.sol/LoanEnd.json';
const loanLiqJson = './contracts/facets/liquidation/LoanLiquidation.sol/LoanLiquidation.json';
const oracleJson = './contracts/facets/oracle/OracleManager.sol/OracleManager.json';
const liqAmountJson = './contracts/utils/LiquidAmount.sol/LiquidAmount.json';
const COUNTER_FILE = path.join('./files', 'counter.json');
const BLOCK_FILE = path.join('./files', 'block.json');

/*____________________________ counter _____________________________*/
const counterUrl = pathToFileURL(path.resolve(COUNTER_FILE));
const counterObj = await import(counterUrl.href, {with: {type: 'json'}});
let counter = counterObj.default.startFrom;

/*______________________________ block _____________________________*/
const blockUrl = pathToFileURL(path.resolve(BLOCK_FILE));
const blockObj = await import(blockUrl.href, {with: {type: 'json'}});
let currBlock = blockObj.default.startFrom;

/*___________________________ premitives ___________________________*/
let provider = wsConnect(SONIC_WS);
const baseModerator = new ethers.Wallet(MODERATOR_KEY, provider);
const moderator = new NonceManager(baseModerator);

/*_____________________ instantiate contracts ______________________*/ 
const loanMgmt = await addContract(loanMgmtJson);
const loanLiq = await addContract(loanLiqJson);
const oracle = await addContract(oracleJson);
const liqAmount = await addContract(liqAmountJson);

console.info(`\u{1F5C3}  Contracts added!`);

/*______________________ listen to provider ________________________*/
provider.on('error', (error) => {
  
  console.error(`Provider error:\n ${error}`);
  provider = wsConnect(SONIC_WS);

});

/*_____________ task A: listen to on-chain events __________________*/
loanMgmt.on('NewLoanAdded', async (realLoanId) => {

  try{
    currBlock = await provider.getBlockNumber();

    await addLoan(realLoanId);
    updateCounter();
    updateBlock();
  }catch(err){
    console.error(`\u{1F6A8} Error on NewLoanAdded listener:\n${err}`);
  }

})

loanMgmt.on('LoanRepaid', async (realLoanId) => {

  try{
    currBlock = await provider.getBlockNumber();

    // Delete the loan
    await delRepaidLoan(realLoanId);
    // Update block file
    updateBlock();

  }catch(err){
    console.error(`\u{1F6A8} Error on LoanRepaid listener:\n${err}`);
  }

})

oracle.on('LoanStatus', async (realLoanId, loanId, isLiquid, healthFactor, lpToken, lpAmount, debtValue) => {

  try{
    // Get loan from storage
    const hf = ethers.formatEther(healthFactor);
    const index = await redisClient.get(realLoanId.toString());
    const loan = JSON.parse(await redisClient.get(index));

    // Loan state
    const loanId = loan.id;
    const isLiq = loan.isLiquidating;

    // Check to liquidate
    if(isLiquid && !isLiq){
      
      // Update loan state on storage
      loan.isLiquidating = true;
      redisClient.set(index, JSON.stringify(loan));

      // Update loan flag
      await updateFlag(loanId);

      // Liquidate partial or all
      if(0.95 < hf && hf < 1){
        const partValue = await liqAmount.closeFactor(loanId, debtValue, 1);
        await liqPartial(loanId, partValue, index, loan);
        await updateFlag(loanId);
      }
      if(hf <= 0.95){
        await liqAll(loanId, index, loan);
        await updateFlag(loanId);
      }
      // Update loan flag
    }

  }catch(err){
    console.error(`\u{1F6A8} Error on LoanStatus listener:\n${err}`)
  }

})

/*___________________ task B: detect liq loans _____________________*/
async function checkLoans() {

  try{
    console.info(`\u{23F1}  Checking loans ... `);
    for (let i = 0; i < counter; i++) {
      const recordStr = await redisClient.get(i.toString());
      if(!recordStr){
        console.info(`loan[${i}] ignored`);
      }else{
        const record = JSON.parse(recordStr);
        if(!record.isLiquidating){
          await liqDetect(record.id);
        }
      }

    }
  }catch(err){
    console.error(`\u{1F6A8} Error in checkLoans():\n${err}`)
  }

}

/*______________________ helper functions __________________________*/


function httpConnect(endpoint) {

  try{
    const wsProvider = new ethers.JsonRpcProvider(endpoint);
    return wsProvider;
  }catch(err){
    console.error(`\u{1F6A8} Error in wsConnect():\n${err}`);
  }

}

function wsConnect(endpoint) {

  try{
    const wsProvider = new ethers.WebSocketProvider(endpoint);
    return wsProvider;
  }catch(err){
    console.error(`\u{1F6A8} Error in wsConnect():\n${err}`);
  }

}

async function addContract(jsonPath) {

  try{
    const jsonFile = await import(jsonPath, {with: {type: 'json'}});
    const _abi = jsonFile.default.abi;
    const contract = new ethers.Contract(DIAMOND, _abi, moderator);
    
    return contract;
  }catch(err){
    console.error(`\u{1F6A8}  Error in addContract():\n${err}`);
  }

}

async function addLoan(loanId) {

  try{
    const loan = {
      id: loanId,
      isLiquidating: false,
    }
    redisClient.set(counter.toString(), JSON.stringify(loan));
    redisClient.set(loanId.toString(), counter.toString());

    console.info(`\u{1F4DD} block[${currBlock}]: loan[${counter}] ----> ${loanId.substring(0,10)}...`);

    counter++;
  }catch(err){
    console.error(`\u{1F6A8} Error in addLoan():\n${err}`)
  }

}

async function delRepaidLoan(loanId){

  try{
    // Get the index of loan to delete
    const index = await redisClient.get(loanId.toString());
    // Delete loan from storage
    redisClient.del(index);
    // Update storage
    shiftLoans(index);

    console.info(`\u{1F4DD} block[${currBlock}]: loan[${counter}] ----> ${loanId.substring(0,10)}... ----> \u{1F5D1}`);
  }catch(err){
    console.error(`\u{1F6A8} Error in delRepaidLoan():\n${err}`);
  }

}

function updateCounter() {// Updates counter file

  try{
    const prevCounter = counterObj.default.startFrom;
    counterObj.default.startFrom++;
    outbound(COUNTER_FILE, JSON.stringify(counterObj.default, null, 2));
    console.info(`Counter file: ${prevCounter} ----> ${counterObj.default.startFrom}`);
  }catch(err){
    console.error(`\u{1F6A8} Error in updateCounter():\n${err}`);
  }

}

function updateBlock() {// Updates block file

  try{
    const prevBlock = blockObj.default.startFrom;
    const blockFile = {
      startFrom: currBlock
    }
    outbound(BLOCK_FILE, JSON.stringify(blockFile, null, 2));
    console.info(`Block file: block[${prevBlock}] ----> block[${currBlock}] `);
  }catch(err){
    console.error(`\u{1F6A8} Error in updateBlock():\n${err}`);
  }

}

async function shiftLoans(id) {

  try{
    for(let i = id + 1; i < counter; i++){
      // Get loan
      const loan = await redisClient.get(i.toString());
      // Shift loan to left
      redisClient.set((i - 1).toString(), loan);
      // Delete loan previous location
      redisClient.del(i.toString());
    }

    // Update counter file
    counter--;
    counterObj.default.startFrom = counter;
    outbound(COUNTER_FILE, JSON.stringify(counterObj.default, null, 2));
  }catch(err){
    console.error(`\u{1F6A8} Error in shiftLoans():\n${err}`);
  }

}

async function updateFlag(id) {

  try{
    const GAS_BUMP = ethers.parseUnits('1', 'gwei');
    const updateTx = await loanMgmt.updateLoanFlag(id, {
      maxPriorityFeePerGas: (await provider.getFeeData()).maxPriorityFeePerGas + GAS_BUMP
    });
    await updateTx.wait();

    console.info(`\u{1F6A9} Loan flag updated`);
  }catch(err){
    console.error(`\u{1F6A8} Error in updateFlag():\n${err}`)
  }

}

async function liqPartial(_id, _value, _index, _loan) {

  try{

    // Liquidation
    const liqTx = await loanLiq.liquidWithAmount(_id, _value);
    await liqTx.wait();

    // Update loan state
    _loan.isLiquidating = false;
    redisClient.set(_index, _loan);
    
    console.info(`\u{1F4B5} loan[${_index}] liquidated partially`);

  }catch(err){
    console.error(`\u{1F6A8} Error in liqPartial():\n${err}`)
  }

}

async function liqAll(_id, _index, _loan) {

  try{

    // Liquidation
    const liqTx = await loanLiq.liquidAll(_id);
    await liqTx.wait();

    console.info(`\u{1F4B0} loan[${_index}] liquidated completely`);
    // Update storage
    _loan.isLiquidating = false;
    redisClient.del(_index);
    shiftLoans(_index);

    console.info(`\u{1F5C2} Storage: loan[${_index}] ----> \u{1F5D1}`)

  }catch(err){
    console.error(`\u{1F6A8} Error in liqPartial():\n${err}`)
  }

}

async function liqDetect(id) {

  try{
    if(!id){
      console.warn(`\u{26A0} undefined/null loan index detected`);
    }
    const GAS_BUMP = ethers.parseUnits('1', 'gwei');
    const maxPriorityFeePerGas = (await provider.getFeeData()).maxPriorityFeePerGas + GAS_BUMP;
    const detTx = await oracle.liquidationDetect(id, {maxPriorityFeePerGas});
    await detTx.wait();
    if(!detTx){
      console.warn(`\u{26A0} Detect: \u{1F50E} loan[${id}] ---------> undefined/null`);
    }
  }catch(err){
    console.error(`\u{1F6A8} Error in liqDetect():\n${err}`)
  }

}

async function syncWithChain() {

  try{
    console.info(`\u{1F6A3} Syncing with chain ...`);
    // Get from and to to check
    const countFrom = counterObj.default.startFrom;
    const start = blockObj.default.startFrom;
    const latest = await provider.getBlockNumber();
    const loanAdd = loanMgmt.filters.NewLoanAdded();

    // Get all new loans
    const batchSize = 20_000;
    for(let from = start; from <= latest; from += batchSize){
      const to = Math.min(from + batchSize - 1, latest);
      const loans = await loanMgmt.queryFilter(loanAdd, from, to);
      loans.forEach(async (loan) => {
        if(!loan.args.isRepaid){
          await addLoan(loan.args.realLoanId);
          updateCounter();
          updateBlock();
        }
      })
    }

    console.info(`\u{1F9CE} Syncing done!`);

  }catch(err){
    console.error(`\u{1F6A8} Error in syncWithChain():\n${err}`);
  }

}

/*___________________________ run bot ______________________________*/
(async function () {

  console.info(`\u{1F680} Bot launched ...`);
  console.info(`\u{1F6F0}  Is listening to chain ...`);

  // Sync with added loan
  await syncWithChain();

  cron.schedule('* */2 * * * *', checkLoans);

})();


// Must be synced with chain by listening to blocks from startFrom to current block

Result:

[dotenv@17.2.0] injecting env (26) from .env (tip: 🔐 prevent building .env in docker: https://dotenvx.com/prebuild)
🔌 Redis connected!
🗃  Contracts added!
🚀 Bot launched ...
🛰  Is listening to chain ...
🚣 Syncing with chain ...
📝 block[39834487]: loan[4] ----> 0x978c9c8f...
🧎 Syncing done!
Counter file: 4 ----> 5
Block file: block[39834487] ----> block[39834487] 
⏱  Checking loans ... 
🚨 Error in liqDetect():
Error: missing revert data (action="estimateGas", data=null, reason=null, transaction={ "data": "0x574f93cb00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000060978c9c8fd998b7997ae854ad8cef8fb9b8a698f99d09e5f368b6ccf92be99bda930c9c9fd582b1090ae834ad8cef8fb0b7a037f21d09e5f368b6ccf11be99bda930c9c9fd582b1090ae834ad8cef8fb0b7a037f21d09e5f368b6ccf11be99bda", "from": "0x1164E83a5313089422e0ef4428dE07520c746D79", "to": "0x8C2025e8d92c7411b6eb450FF886022f38b07487" }, invocation=null, revert=null, code=CALL_EXCEPTION, version=6.15.0)
⏱  Checking loans ... 
⏱  Checking loans ... 
🚨 Error in liqDetect():
Error: missing revert data (action="estimateGas", data=null, reason=null, transaction={ "data": "0x574f93cb00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000060978c9c8fd998b7997ae854ad8cef8fb9b8a698f99d09e5f368b6ccf92be99bda930c9c9fd582b1090ae834ad8cef8fb0b7a037f21d09e5f368b6ccf11be99bda930c9c9fd582b1090ae834ad8cef8fb0b7a037f21d09e5f368b6ccf11be99bda", "from": "0x1164E83a5313089422e0ef4428dE07520c746D79", "to": "0x8C2025e8d92c7411b6eb450FF886022f38b07487" }, invocation=null, revert=null, code=CALL_EXCEPTION, version=6.15.0)
🚨 Error in liqDetect():
Error: missing revert data (action="estimateGas", data=null, reason=null, transaction={ "data": "0x574f93cb00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000060978c9c8fd998b7997ae854ad8cef8fb9b8a698f99d09e5f368b6ccf92be99bda930c9c9fd582b1090ae834ad8cef8fb0b7a037f21d09e5f368b6ccf11be99bda930c9c9fd582b1090ae834ad8cef8fb0b7a037f21d09e5f368b6ccf11be99bda", "from": "0x1164E83a5313089422e0ef4428dE07520c746D79", "to": "0x8C2025e8d92c7411b6eb450FF886022f38b07487" }, invocation=null, revert=null, code=CALL_EXCEPTION, version=6.15.0)

Code Snippet

async function liqDetect(id) {

  try{
    if(!id){
      console.warn(`\u{26A0} undefined/null loan index detected`);
    }
    const GAS_BUMP = ethers.parseUnits('1', 'gwei');
    const maxPriorityFeePerGas = (await provider.getFeeData()).maxPriorityFeePerGas + GAS_BUMP;
    const detTx = await oracle.liquidationDetect(id, {maxPriorityFeePerGas});
    await detTx.wait();
    if(!detTx){
      console.warn(`\u{26A0} Detect: \u{1F50E} loan[${id}] ---------> undefined/null`);
    }
  }catch(err){
    console.error(`\u{1F6A8} Error in liqDetect():\n${err}`)
  }

}

Contract ABI

[
    {
      "inputs": [
        {
          "internalType": "int256",
          "name": "price",
          "type": "int256"
        }
      ],
      "name": "InvalidPrice",
      "type": "error"
    },
    {
      "inputs": [
        {
          "internalType": "address",
          "name": "lpTokenAddr",
          "type": "address"
        },
        {
          "internalType": "bool",
          "name": "configuration",
          "type": "bool"
        }
      ],
      "name": "LPTokenNotConfigured",
      "type": "error"
    },
    {
      "inputs": [],
      "name": "OnlyAdminIsAllowedToDoThisJob",
      "type": "error"
    },
    {
      "inputs": [
        {
          "internalType": "uint256",
          "name": "lastInterval",
          "type": "uint256"
        },
        {
          "internalType": "uint256",
          "name": "stalenessTreshold",
          "type": "uint256"
        }
      ],
      "name": "PriceDataStale",
      "type": "error"
    },
    {
      "inputs": [
        {
          "internalType": "address",
          "name": "feed",
          "type": "address"
        },
        {
          "internalType": "bool",
          "name": "activation",
          "type": "bool"
        }
      ],
      "name": "PriceFeedNotActive",
      "type": "error"
    },
    {
      "anonymous": false,
      "inputs": [
        {
          "indexed": false,
          "internalType": "address",
          "name": "lpToken",
          "type": "address"
        },
        {
          "indexed": false,
          "internalType": "uint256",
          "name": "liquidationThreshold",
          "type": "uint256"
        },
        {
          "indexed": false,
          "internalType": "uint256",
          "name": "liquidationBonus",
          "type": "uint256"
        },
        {
          "indexed": false,
          "internalType": "uint256",
          "name": "volatilityDiscount",
          "type": "uint256"
        },
        {
          "indexed": false,
          "internalType": "bool",
          "name": "isActive",
          "type": "bool"
        }
      ],
      "name": "LPTokenConfigured",
      "type": "event"
    },
    {
      "anonymous": false,
      "inputs": [
        {
          "indexed": false,
          "internalType": "bytes",
          "name": "realLoanId",
          "type": "bytes"
        },
        {
          "indexed": false,
          "internalType": "bytes32",
          "name": "loanId",
          "type": "bytes32"
        },
        {
          "indexed": false,
          "internalType": "bool",
          "name": "isLiquid",
          "type": "bool"
        },
        {
          "indexed": false,
          "internalType": "uint256",
          "name": "healthFactor",
          "type": "uint256"
        },
        {
          "indexed": false,
          "internalType": "address",
          "name": "lpToken",
          "type": "address"
        },
        {
          "indexed": false,
          "internalType": "uint256",
          "name": "lpAmount",
          "type": "uint256"
        },
        {
          "indexed": false,
          "internalType": "uint256",
          "name": "debtValue",
          "type": "uint256"
        }
      ],
      "name": "LoanStatus",
      "type": "event"
    },
    {
      "anonymous": false,
      "inputs": [
        {
          "indexed": false,
          "internalType": "address",
          "name": "lpToken",
          "type": "address"
        },
        {
          "indexed": false,
          "internalType": "address",
          "name": "token0",
          "type": "address"
        },
        {
          "indexed": false,
          "internalType": "address",
          "name": "token1",
          "type": "address"
        },
        {
          "indexed": false,
          "internalType": "address",
          "name": "token0Feed",
          "type": "address"
        },
        {
          "indexed": false,
          "internalType": "uint8",
          "name": "token0DeciDigit",
          "type": "uint8"
        },
        {
          "indexed": false,
          "internalType": "bool",
          "name": "token0Activation",
          "type": "bool"
        },
        {
          "indexed": false,
          "internalType": "address",
          "name": "token1Feed",
          "type": "address"
        },
        {
          "indexed": false,
          "internalType": "uint8",
          "name": "token1DeciDigit",
          "type": "uint8"
        },
        {
          "indexed": false,
          "internalType": "bool",
          "name": "token1Activation",
          "type": "bool"
        }
      ],
      "name": "PriceFeedSet",
      "type": "event"
    },
    {
      "inputs": [
        {
          "internalType": "address",
          "name": "lpToken",
          "type": "address"
        },
        {
          "internalType": "uint256",
          "name": "lpAmount",
          "type": "uint256"
        },
        {
          "internalType": "uint256",
          "name": "debtValue",
          "type": "uint256"
        }
      ],
      "name": "calculateHealthFactor",
      "outputs": [
        {
          "internalType": "uint256",
          "name": "",
          "type": "uint256"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "address",
          "name": "lpToken",
          "type": "address"
        },
        {
          "internalType": "uint256",
          "name": "liquidationThreshold",
          "type": "uint256"
        },
        {
          "internalType": "uint256",
          "name": "liquidationBonus",
          "type": "uint256"
        },
        {
          "internalType": "uint256",
          "name": "volatilityDiscount",
          "type": "uint256"
        }
      ],
      "name": "configureLPToken",
      "outputs": [],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "address",
          "name": "asset",
          "type": "address"
        }
      ],
      "name": "getAssetPrice",
      "outputs": [
        {
          "internalType": "uint256",
          "name": "",
          "type": "uint256"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "address",
          "name": "lpToken",
          "type": "address"
        },
        {
          "internalType": "uint256",
          "name": "amount",
          "type": "uint256"
        }
      ],
      "name": "getLPTokenValue",
      "outputs": [
        {
          "internalType": "uint256",
          "name": "",
          "type": "uint256"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "address",
          "name": "lpToken",
          "type": "address"
        },
        {
          "internalType": "uint256",
          "name": "lpAmount",
          "type": "uint256"
        },
        {
          "internalType": "uint256",
          "name": "debtValue",
          "type": "uint256"
        }
      ],
      "name": "isValidLiquidation",
      "outputs": [
        {
          "internalType": "bool",
          "name": "isLiquid_",
          "type": "bool"
        },
        {
          "internalType": "uint256",
          "name": "healthFactor_",
          "type": "uint256"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "bytes",
          "name": "realLoanId",
          "type": "bytes"
        }
      ],
      "name": "liquidationDetect",
      "outputs": [],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "address",
          "name": "lpToken",
          "type": "address"
        },
        {
          "internalType": "address",
          "name": "feed0",
          "type": "address"
        },
        {
          "internalType": "address",
          "name": "feed1",
          "type": "address"
        }
      ],
      "name": "setPriceFeed",
      "outputs": [],
      "stateMutability": "nonpayable",
      "type": "function"
    }
  ]

Errors

Error: missing revert data (action="estimateGas", data=null, reason=null, transaction={ "data": "0x574f93cb00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000060978c9c8fd998b7997ae854ad8cef8fb9b8a698f99d09e5f368b6ccf92be99bda930c9c9fd582b1090ae834ad8cef8fb0b7a037f21d09e5f368b6ccf11be99bda930c9c9fd582b1090ae834ad8cef8fb0b7a037f21d09e5f368b6ccf11be99bda", "from": "0x1164E83a5313089422e0ef4428dE07520c746D79", "to": "0x8C2025e8d92c7411b6eb450FF886022f38b07487" }, invocation=null, revert=null, code=CALL_EXCEPTION, version=6.15.0)

Environment

Distributor ID: Ubuntu
Description: Ubuntu 24.04.2 LTS
Release: 24.04
Codename: noble

Environment (Other)

Nodejs v20.19.4

Metadata

Metadata

Assignees

Labels

investigateUnder investigation and may be a bug.v6Issues regarding v6

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions