10

I'm working on a Chrome Extension but lately I've noticed I've been getting the following error (pointing to the first line of popup.html):

Unchecked runtime.lastError: Could not establish connection. Receiving end does not exist.

I've found a similar question here. But the error there is caused by the background property which I haven't declared on my manifest.

I'm using chrome.extension.onMessage.addListener on the contents.js script to listen for events and chrome.tabs.sendMessage on the popup.js script to send the events. Most of the time everything works fine, but sometimes I get the above error and none of the requests do anything.

The manifest.json is of the following format:

{
    "manifest_version": 2,
    "name": "APP_NAME",
    "description": "APP_DESCRIPTION",
    "version": "APP_VERSION",
    "browser_action": {
        "default_icon": "icon.png",
        "default_popup": "popup.html"
    },
    "permissions": [
        "activeTab",
        "storage",
        "clipboardRead",
        "clipboardWrite"
    ],
    "content_scripts": [
        {
            "matches": [
                "<all_urls>"
            ],
            "js": [
                "content.js"
            ],
            "css": [
                "content.css"
            ]
        }
    ]
}

Message Listener Example:

chrome.extension.onMessage.addListener(function(request, sender, sendResponse) {
  if (request.action === "this") console.log({
    dom: doThis()
  });
  if (request.action === "that") sendResponse({
    dom: doThat()
  });
  else if (request.action === "other") doOther();
  else sendResponse({});
});

Message Sender Example:

function getSelectedTab() {
  return new Promise(function(resolve) {
    chrome.tabs.getSelected(null, resolve);
  });
}

function sendRequest(data) {
  data = data || {
    action: undefined
  };
  return new Promise(function(resolve) {
    getSelectedTab().then(function(tab) {
      chrome.tabs.sendMessage(tab.id, data, resolve);
    });
  });
}

Send Request Invocation Example:

document.querySelector("#this").addEventListener("click", function() {
  sendRequest({
    action: "this"
  }).then(function(res) {
    console.log(res);
  });
});

document.querySelector("#that").addEventListener("hover", function() {
  sendRequest({
    action: "that"
  });
});

addEventListener("blur", function() {
  sendRequest({
    action: "other"
  });
});
nick zoum
  • 7,216
  • 7
  • 36
  • 80
  • It means you're sending a message but there's no active chrome.runtime.onMessage listener yet. Your content scripts run when a web page has finished loading, which is the default behavior. Depending on how your extension uses messaging various solutions are possible. Without a real [MCVE](/help/mcve) it's not clear what to suggest. – wOxxOm May 09 '19 at 09:25
  • (or you're using sendResponse without specifying a callback in chrome.runtime.sendMessage) – wOxxOm May 09 '19 at 09:33
  • @wOxxOm Updated the request calls. I still get the same error. (Still can't find any reliable pattern on when the error is thrown. I could start chrome, do all of the actions in extension and not get an error, then restart chrome and none of the actions are working) – nick zoum May 09 '19 at 10:29
  • @wOxxOm I added example scripts to the question but I doubt they will be of much assistance. – nick zoum May 09 '19 at 10:49
  • @wOxxOm They are called from dom event listeners (examples added). It is possible that some events could be triggered before the listener is added but there are times I've for the page to fully and seen the content script state the listener has been added and still get the error – nick zoum May 09 '19 at 11:42
  • 1
    If you have a different window focused (like devtools for the popup) then your `hover` listener will try to send a message into devtools window and fail since it has no tabs and no content scripts. Anyway, there are no obvious problems in your code so simply check for chrome.runtime.lastError (and optionally log it) in sendMessage - replace `resolve` with something like data => chrome.runtime.lastError ? console.warn(chrome.runtime.lastError) : resolve(data) – wOxxOm May 09 '19 at 11:58

1 Answers1

26

I'm not sure if my answer good for given case, but if you reading it, you faced this kind of problem, and probably my answer will help you.

I spent a lot of time, trying to understand why it sometimes throws this error, while I'm working at dev version, and doesn't do it for released version of my extension. Then I understood, that after every code save, it updates at chrome, and creates new content version of script. So if you don't reload page, where you used previous version of your code to create context.js and trying it again with updated version, it throws this error.

I kinda wasted about one full day to figure it out, it's simply, but there a lot of answers in stackoverflow about this case, so you used to try them, and not think with your brain. Don't be like me:)

RomanistHere
  • 795
  • 7
  • 17