How to handle “Unchecked runtime.lastError: The message port closed before a response was received”?

When you specify a callback for sendMessage you’re telling the API that you NEED a response so when your content script doesn’t respond using sendResponse the API thinks something terrible happened and reports it as such!

Reminder: when editing content scripts make sure to reload both the extension on chrome://extensions page and the tabs that should have this content script.

You don’t need any response:

  • Remove the callback in sendMessage

    chrome.tabs.sendMessage(tabs[0].id, {request: "Requesting headline"});
    
  • Remove return true – all it does currently is telling the API to keep the messaging port open indefinitely, which will never be used by you, so it’s just a memory leak source.

    chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
      // do something
      // don't return true
      // ManifestV2: don't call sendResponse
      // ManifestV3 bug: uncomment the next line
      // sendResponse();
    });
    

    For ManifestV3 in Chrome 99, 100, 101 you need a dummy sendResponse() call.

You need a response:

  • Replace return true with sendResponse

    chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
      sendResponse('whatever');
    });
    

You need a response from asynchronously running code such as chrome API callback:

  • Keep return true

  • Call sendResponse(someImportantData) inside the callback

    chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
      chrome.storage.local.set({foo: 'bar'}, () => {
        sendResponse('whatever');
      });
      return true;
    });
    

Leave a Comment