Troubleshooting "Uncaught (in promise) Error: Could not establish connection. Receiving end does not exist."

This is a story about the following mysterious error that occurred after I changed the Manifest file of my Chrome extension 'Our Mouse Gesture' from v2 to v3.

Uncaught (in promise) Error: Could not establish connection. Receiving end does not exist.

I was confused, "What does it mean that the error occurs on line 0 of the file?", so this is a memorandum of how to deal with it.

f:id:holyblue:20220710192456p:plain

1. What is "Uncaught (in promise) Error" ?

The Manifest v3 API reference states that API functions that specify a callback function as an argument, such as chrome.runtime, return a "Promise" as the return value.
This return value "Promise" seems to be returned only when no callback function is specified as an argument of the API function.

※API Reference : chrome.runtime.sendMessage https://developer.chrome.com/docs/extensions/reference/runtime/#method-sendMessage

f:id:holyblue:20220710193107p:plain

And the message "Uncaught (in promise) Error" seemed to mean that error handling was not used with this return value "Promise". In other words, I think this means that if you write the following as before, this error message will be displayed.

let message = "test";
chrome.runtime.sendmessage(message, (response)=> {
   // Callback Function Processes
});

Therefore, in order to handle errors with "Promise", you need to change the writing style to use the Promise return value instead of specifying the callback function as an argument.

let message = "test";
let rtnPromise = chrome.runtime.sendmessage(message);
rtnPromise
   .then((response)=> {
        // Callback Function Processes
   })
   .catch((error)=> {
        // Error Handling Processes
   )}

By doing this, you can suppress the occurrence of the error "Uncaught (in promise) Error" and write your own handling process when an error occurs.

2. What is "Could not establish connection. Receiving end does not exist." ?

If you handle errors as described above, the message "Uncaught (in promise) Error" will no longer appear. However, the error "Could not establish connection. Receiving end does not exist." still occurs.

So, when does this "Could not establish connection. Receiving end does not exist." occur?

Currently, I have confirmed that this error occurs when executing the following Chrome API.

  • chrome.tabs.sendMessage()
let rtnPromise = chrome.tabs.sendMessage(tabid, message);
rtnPromise
   .then((response)=> {
        // Callback Function Processes
   })
   .catch((error)=> {
        // Error Handling Processes
   )}

This error seems to occur when you send a message to this specific tab and that tab is unable to receive messages.

What I can say with certainty is that this error definitely occurred when chrome.tabs.sendMessage was sent to a tab displaying a screen managed by Chrome whose URL starts with "chrome://".

[For Example]

  • chrome://newtab/ :new tab screen
  • chrome://extensions/ :Chrome extension management screen

Therefore, if the URL of the message destination tab is a screen managed by Chrome, a possible countermeasure is not to send the message.
However, since it is not compatible with Chromium Edge if the URL starts with "chrome://", it would be better to send a message when the URL starts with "http".

And I have confirmed that this error also occurs on Chrome Web Store pages.

2.2. Error case 2 : When Content Script is unable to receive messages (frozen?)

The second case is when there is a problem with the Content Script of the tab on the side that receives messages, and the tab is unable to receive messages sent with chrome.tabs.sendMessage.
In the tab where this error occurred, the Mouse Gesture I created was not working properly, so I guessed that the problem was with Content Script.

Afterword

This article was translated into English because the version written in Japanese in 2022 received a lot of access.
I hope I can help someone facing a similar problem.
Thank you for reading to the end.