Reputation: 6085
There are plenty of issues open on the subject, but I couldn't find an explanation in my case. Here is a minimal test case:
Here is my manifest.json
{
"manifest_version": 3,
"name": "Test",
"version": "1.0",
"description": "Test extension",
"icons": {
"48": "dark.png"
},
"background": {
"service_worker": "button.js"
},
"permissions": [
"activeTab"
],
"action": {
"default_icon": "dark.png",
"default_title": "DarkTheme"
},
"content_scripts": [
{
"matches": [
"<all_urls>"
],
"js": [
"dark.js"
]
}
]
}
button.js
chrome.action.onClicked.addListener(tab => {
console.log('clicked')
chrome.tabs.sendMessage(tab.id, { value: false })
});
dark.js
chrome.runtime.onMessage.addListener(request => {
console.log('received', request)
})
So, basically, my listener is set right at the start, and only when I press the button do I send a message. How come I can receive this error when I press the button?
Uncaught (in promise) Error: Could not establish connection. Receiving end does not exist.
Tested on Chromium Version 100.0.4896.75 (Build officiel) snap (64 bits)
Upvotes: 37
Views: 81130
Reputation: 17354
Some of the above answers helped me solve the problem. Here arethe steps I took. Since this is pretty complicated sharing it to help others
Remove all unwanted code. Look for misssing ; in code etc at the end of statements and functions which may not error out but can be a problem. Just remove all your code and put some test code instead.
When you refresh the extension in Chrome, make sure to reload the page. It is also advisable to open the window again (fresh start).
The code may not work for some websites. Like for me, it does not work on yahoo (it blocks injections I think) but works on cnn and other sites. Make sure to test it on a number of sites.
The below error can be misleading. It is also thrown when the page does not allow injection which is not mentioned anywhere in the documentation. Your first step is to test it on another site.
Uncaught (in promise) Error: Could not establish connection. Receiving end does not exist.
I hope this helps.
Upvotes: 0
Reputation: 91
Had this and a lot of more errors. Removed all of them by setting Evernote Chrome extention to 'look only on press' (or simply disabled). Solution from https://stackoverflow.com/a/75723433/17137584
There was 2 types of errors, each of up to ten variations (different ends):
commons.js:2 Channel: Error in handleResponse UNK/SW_UNREACHABLE ...
commons.js:2 Uncaught (in promise) Error: Could not establish connection. Receiving end does not exist.
Upvotes: 4
Reputation: 3623
It took me hours to figure out the cause of this error because everything in my code seems correct. Turns out I just need to refresh both the extension and the webpage to see it working.
Upvotes: 47
Reputation: 4290
I had some issues with this followed the docs here as stated above https://developer.chrome.com/docs/extensions/mv3/messaging/ this works for v3
popup.js
chrome.tabs.query({
active: true,
currentWindow: true
}, function(tabs) {
chrome.scripting.executeScript({
target: {
tabId: tabs[0].id
},
function: sendData,
});
});
const sendData = async () => {
chrome.runtime.sendMessage({
count: 12,
data: []
}, function(response) {
console.log(response.received);
});
}
Background.js
chrome.runtime.onMessage.addListener((data, sender, sendResponse) => {
if (data) {
// Do something amazing
}
sendResponse({
received: true
});
});
Upvotes: 2
Reputation: 401
Thanks for posting, I also had a similar issue and for my particular problem I could not find a proper answer in particular for Google Chrome Extension Manifest Version 3.
In my case, I want to send the idle state with chrome.idle.onStateChanged
from a background.js
to a contentScript.js
. As I am building an extension for reddit, the contentScript.js
is only injected into pages which match the URL pattern for reddit.
chrome.idle.onStateChanged.addListener(
(browserActivityState) => {
chrome.tabs.query({active: true, currentWindow: true}, (tabs) => {
chrome.tabs.sendMessage(tabs[0].id, { browserActivityState: browserActivityState });
});
}
)
Then I got the same error as you.
Uncaught (in promise) Error: Could not establish connection. Receiving end does not exist.
I realized while reading the error message, that this happened because I want to send a message to a page which does not have contentScript.js
.
I also noticed that it occurred for when I had Chrome but not a reddit page open, I then for example locked my screen which triggers an idle change event and hence my background.js
tries send a message to a page.
The problem is, reddit has not been open in the last active tab and therefore the tab to which this message has been sent does not have a contentScript.js
injected.
As preliminary solution, not sure if this is the best style but it does the job, I check if the tab I am sending a message to does match the URL of pages where I am injecting the contentScript.js
into with if (tabs[0].url.match('https:\/\/.*.reddit.com\/.*'))
.
chrome.idle.onStateChanged.addListener(
(browserActivityState) => {
console.log('browserActivityState changed')
chrome.tabs.query({active: true, currentWindow: true}, (tabs) => {
if (tabs[0].url.match('https:\/\/.*.reddit.com\/.*')) {
chrome.tabs.sendMessage(tabs[0].id, { browserActivityState: browserActivityState });
}
});
}
)
This ensures, I am not sending a message to a tab with 'no receiving end' and so far the error is gone.
Maybe you can look in this direction as well for your problem solving.
I hope I was able to help a bit.
Upvotes: 30
Reputation: 1
When sending message from content script to background, it should be like below.
chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
chrome.tabs.sendMessage(tabs[0].id, {greeting: "hello"}, function(response) {
console.log(response.farewell);
});
});
Link: https://developer.chrome.com/docs/extensions/mv3/messaging/
Upvotes: 0