Error: "Could not establish connection. Receiving end does not exist."

6,733 views
Skip to first unread message

Brad Zickafoose

unread,
Dec 16, 2022, 9:49:49 AM12/16/22
to Chromium Extensions
Hi,

I have an extension that has a background.js, which includes the Alarms and Tabs api.

I want to run a function when the content-script.js is injected and then run the function again at a set interval of every 10 seconds.

However, the chrome.tabs.sendMessage keeps showing a chrome.runtime.lastError of "Could not establish a connection. Receiving end does not exist."

Obviously, I'm doing something wrong here, I'm just not 100% sure of what it is.

Am I doing this right?

The relevant code looks like:

manifest.js
"permissions": ["alarms", "tabs"],

background.js
try {
     chrome.alarms.create("myFunctionAlarm", { when: Date.now() + 10000 });
     chrome.alarms.onAlarm.addListener(function (alarm) {
          if (alarm.name == "myFunctionAlarm") {
               getCurrentTab().then((tab) => {
                    chrome.tabs.sendMessage(tab.id, { name: 'myFunctionAlarm' }, function () {
                         if (!chrome.runtime.lastError) {
                              chrome.alarms.create("myFunctionAlarm", { when: Date.now() + 10000 });
                         }
                    });
               });
          }
     });
} catch (error) {
     console.error(error);
}

content-script.js
try {
     myFunction();
     chrome.runtime.onMessage.addListener(
          function(request, sender, sendResponse) {
               if (request.name === 'myFunctionAlarm') {
                    myFunction();
                    sendResponse();
               {
          }
     );
} catch (error) {
     console.log("Content-Script error:", error);
}

Brad Zickafoose

unread,
Dec 16, 2022, 9:53:10 AM12/16/22
to Chromium Extensions, Brad Zickafoose
Forgot to include this piece of code which also exists in my background.js for getting the current tab:

async function getCurrentTab() {
     let queryOptions = { active: true, lastFocusedWindow: true };
     let [tab] = await chrome.tabs.query(queryOptions);
     return tab;
}

wOxxOm

unread,
Dec 16, 2022, 11:34:16 AM12/16/22
to Chromium Extensions, Brad Z
Content scripts declared in manifest.json or registered in chrome.scripting.registerContentScripts run only when the tab is loaded or reloaded (e.g. via Ctrl-R), so when you install or update your extension the existing tabs don't run your new content scripts automatically in Chrome (they do in Firefox though), whereas the old content scripts that were running previously lose the ability to connect to the extension.

The solution is to re-inject the content script explicitly. You can do it either for all open tabs in chrome.runtime.onInstalled listener (example) or just for the active tab using chrome.scripting.executeScript when the alarm fires. Which one to choose depends on what your extension does. If it's something simple and you only need the content script in onAlarm then executeScript would be a better choice and you won't even need messaging e.g. your injected script would be the contents of myFunction.

Reply all
Reply to author
Forward
0 new messages