Uncaught (in promise) Error: Could not establish connection. Receiving end does not exist. Can’t sendMessage from background.js to offscreen.js

I’m trying to send a message to offscreen.js from background.js to use service workers to process DOM content. The offscreen document is apparently created, but when I send a message to it, it says it doesn’t exist. background.js is reached by contentScript.js; the problem is with the offscreen setup.

I tried checking if the offscreen document is created, but it says it exists even when I manually typed console.log(await chrome.offscreen.hasDocument()); in the console window of the background.js service worker (printed true), so it doesn’t just close itself after being created. It also exists at the time of sendMessage because it’s triggered only when it’s created (or am I missing something?). So my guess is it’s somehow inaccessible to background.js though it ‘exists’. Here’s the Sources window of background.js:

enter image description here

Should offscreen.js and offscreen.html be displayed here? Does it mean it’s not accessible to background.js?

background.js:

chrome.runtime.onMessage.addListener(async (message, sender, sendResponse) => {
  if (message.type === 'another mt (from contentscript)') {
    await ensureOffscreen();

    console.log("CAME BACK");

    const result = await chrome.runtime.sendMessage({
      type: 'mt',
      param: message.param
    });

    console.log("DONE NOW SENDING");

    sendResponse({ text: result.t });
    return true;
  }
});

async function ensureOffscreen() {

  console.log("REACHED HERE");

  const existing = await chrome.offscreen.hasDocument();
  if (existing) {
  console.log("EXISTS");

  await new Promise(resolve => setTimeout(resolve, 5000));

  return;}

  else{

  await chrome.offscreen.createDocument({
    url: 'offscreen.html',
    reasons: [chrome.offscreen.Reason.DOM_SCRAPING],
    justification: 'Need DOM for processing'
  });

await new Promise((resolve) => {
    const listener = (msg) => {
      if (msg.type === "offscreen-ready") {
        chrome.runtime.onMessage.removeListener(listener);
        setTimeout(resolve, 5000);
      }
    };
    chrome.runtime.onMessage.addListener(listener);
  });


console.log("HERE TOO");

  }

}

offscreen.js:

chrome.runtime.onMessage.addListener((msg, sender, sendResponse) => {

  console.log("offscreen triggered");

  sendResponse({t: "from offscreen"});

  if (msg.type === "mt") {

    console.log("reached here");
    sendResponse({t: "offscreen has spoken"});

    //return true;

    return;

  }
});

chrome.runtime.sendMessage({ type: "offscreen-ready" });

offscreen.html:

<!DOCTYPE html>
<html>
<head>
  <script src="libs/alibthatusesserviceworkers.js"></script>
</head>
<body>
  <canvas id="somecanvas" style="display:none;"></canvas>
  <img id="someimg" crossorigin="anonymous" style="display:none;" />
  <script src="offscreen.js" defer></script>
</body>
</html>

I’ve tried with and without the timeouts/delays, but they don’t work.

REACHED HERE, EXISTS, HERE TOO and CAME BACK are printed, but DONE NOW SENDING isn’t printed because it doesn’t send the message and instead throws the error.