A listener indicated an asynchronous response by returning true, but the message channel closed before a response was received

avatar
Borislav Hadzhiev

Last updated: Apr 5, 2024
5 min

banner

# A listener indicated an asynchronous response by returning true, but the message channel closed before a response was received

The error "A listener indicated an asynchronous response by returning true, but the message channel closed before a response was received" occurs for 2 main reasons:

  1. Having a Chrome extension that causes cross-origin request issues.
  2. Forgetting to return true when fetching data from cross-origin URLs (different domains).

Here is the complete error message.

shell
Uncaught (in promise) >{message: 'A listener indicated an asynchronous response by returning true, but the message channel closed before a response was received'} >[[Prototype]]: Object >constructor: ฦ’ () >[[Prototype]]: Object

Note: if you got the error when developing Chrome extensions, click on the following subheading.

# Having a Chrome extension that causes cross-origin request issues.

The most common cause of the error is having a Chrome extension that causes CORS issues.

CORS is a mechanism that allows a server to use a combination of HTTP headers to indicate from which domains, other than its own, it receives requests.

Starting with Google Chrome version 73, cross-origin requests in content scripts are disallowed.

Many extensions have not yet updated their code which causes the error.

The first thing you should try is to open Chrome in Incognito Mode.

  1. On Windows and Linux, press Ctrl + Shift + N.
  2. On macOS, press: Cmd + Shift + N.

You can also open the browser in Incognito Mode by using the GUI:

  1. Click on the three dots icon in the upper right corner.
  2. Select New Incognito Window.

click three dots new incognito window

Extensions are disabled in incognito mode by default.

Try to visit the page on which you got the error and check your console.

If you no longer see the error, then it is caused by an extension.

# The Ghostery extension causes the error

The error is most commonly caused by the Ghostery extension.

If you use the extension:

  1. Click on its icon to show the extension's settings.
  2. Click on the Trust Site button.

ghostery trust site

If you still get the error when using Ghostery:

  1. Click on the icon to show the extension's settings.
  2. Click on the three dots icon in the top right corner.
  3. Click on Settings.
  4. Click on Trust & Restrict in the left sidebar.
  5. Add "127.0.0.1:*" to the list of Trusted sites.

Here is a short clip that shows how to do this.

add localhost to trusted sites ghostery

Alternatively, you can remove the extension from your browser and install a replacement.

# Checking if a specific extension causes the error

Many extensions cause the error, e.g.:

  • Ghostery
  • Reactime
  • Adobe PDF extension
  • Shoop Cashback & Gutscheine
  • 360 Total Security
  • Norton Safe Web
  • Tampermonkey
  • AdBlock
  • Avast Online Security & Privacy
  • Many different ad block types of extensions

If you need to disable a specific extension to check if it causes the error:

  1. Right-click on the extension's icon.
  2. Select Manage extension.

right click manage extensions

  1. Click on the toggle to disable the extension.

disable specific extension

  1. Once you disable the extension, visit the page that caused the issue and refresh it by clicking F5.

You can repeat the process for each extension that you think might be causing the error.

You can also change the extension's access to the site:

  1. Right-click on the extension's icon in the top menu.

  2. Hover over This can read and change site data setting.

change extension site access

  1. Select When you click the extension if you only want to enable the extension by clicking it when you visit a specific site.

# Forgetting to return true when fetching data from cross-origin URLs

If you are an extension author, you likely forgot to return true when fetching data from cross-origin URLs.

As shown in this chrome issue, when sending a message using a background script, you should return true from the onMessage event handler.

background.js
chrome.runtime.onMessage.addListener((request, sender, sendResponse) => { // ... your code here return true // ๐Ÿ‘ˆ๏ธ Responds asynchronously })

As this section of the chromium documentation states:

  • When performing cross-origin fetches and the server doesn't provide an Access-Control-Allow-Origin response header, perform the fetch request from the extension background page rather than in the content script.

As shown in the code sample, you must return true in the onMessage event handler to keep the message port open while waiting for the response of the asynchronous fetch call.

If you don't return true, the message port closes before the asynchronous request has been completed. This causes the error.

As the error message states:

A listener indicated an asynchronous response by returning true, but the message channel closed before a response was received

The onMessage event is fired when a message is sent from an extension process or a content script.

If the issue persists, try to call the sendResponse function instead.

background.js
chrome.runtime.onMessage.addListener((request, sender, sendResponse) => { // ... your code here sendResponse({message: true}); })

You can also return undefined from sendResponse.

background.js
chrome.runtime.onMessage.addListener((request, sender, sendResponse) => { // ... your code here sendResponse(); })

If you don't have asynchronous fetch requests, you can use the sendResponse() function to solve the error.

However, if you have async fetch requests, make sure to return true.

background.js
chrome.runtime.onMessage.addListener((request, sender, sendResponse) => { // ... your code here return true // ๐Ÿ‘ˆ๏ธ Responds asynchronously })

If you don't call sendResponse and don't return true, the message channel closes immediately before the response has arrived.

A common cause of the error is returning true in your .then() function.

Here is an example of using the return true statement incorrectly.

background.js
// ๐Ÿšจ Incorrect code chrome.runtime.onMessage.addListener(function ( request, sender, sendResponse, ) { if (request.contentScriptQuery == 'queryPrice') { const url = 'https://example.com/price-query?itemId=' + encodeURIComponent(request.itemId); fetch(url).then(response => { // ... return true; // โ›”๏ธ incorrect return statement }); } });

Instead, you should move the return statement after the fetch() call.

background.js
// โœ… Correct code chrome.runtime.onMessage.addListener(function ( request, sender, sendResponse, ) { if (request.contentScriptQuery == 'queryPrice') { const url = 'https://example.com/price-query?itemId=' + encodeURIComponent(request.itemId); fetch(url).then(response => { // ... sendResponse({message: true}); }); // ๐Ÿ‘‡๏ธ use `return true` here return true; // Will respond asynchronously. } });

# Conclusion

To solve the "A listener indicated an asynchronous response by returning true, but the message channel closed before a response was received" error:

  1. Check if the error is caused by an extension and disable it or restrict its access to the site.
  2. Make sure to return true when fetching data from cross-origin URLs.
I wrote a book in which I share everything I know about how to become a better, more efficient programmer.
book cover
You can use the search field on my Home Page to filter through all of my articles.

Copyright ยฉ 2024 Borislav Hadzhiev