Issue with chrome.extension.onMessage being undefined in background script in Chrome extension

Currently facing an issue while attempting to develop a Chrome extension. Occasionally, the chrome.runtime object appears to be incomplete, resulting in missing methods (specifically onMessage, which is essential for my project).

Interestingly, this inconsistency occurs sporadically. I initially thought it might be a timing problem, but I cannot comprehend why establishing a message listener on the background is proving to be challenging.

Provided below is a snippet of my background script:

setTimeout(function () {
    console.log("gogo!");
    chrome.runtime.onMessage.addListener(
        function(request, sender, sendResponse) {
            console.log(sender.tab ?
                        "from a content script:" + sender.tab.url :
                        "from the extension");
            if (request.type == "tab") {
                console.log("tab!");
                sendResponse({status: "ok"});
            }
        }),
    2
});

The issue arises when attempting to refer to "chrome.runtime.onMessage" as it returns as undefined.

Appreciate any insights into this matter!

Update: Simplified the prototype but still encountering errors. Below is a breakdown of the project structure:

$tree
.
├── manifest.json
├── src
│   ├── background.html
│   ├── background.js
│   └── test.js
└── vendor
    └── jquery.js

2 directories, 5 files

Manifest file (manifest.json):

{
    "manifest_version": 2,

    "name": "test",
    "description": "test",
    "version": "1.0",
    "author": "test",

    "homepage_url": "http://www.test.com",

    "content_scripts": [
        {
            "run_at" : "document_idle",
            "matches": ["https://www.google*"],
            "js": ["vendor/jquery.js", "src/test.js"]
        }
    ],

    "background": {
        "page": "src/background.html",
        "persistent": false
    },

    "permissions": [
        "tabs",
        "https://www.google*"
    ]
}

Background HTML file (background.html):

<script src="../vendor/jquery.js"></script>
<script src="background.js"></script>

Background JavaScript file (background.js):

function run () {
    console.log("gogo!");
    chrome.runtime.onMessage.addListener(
        function(request, sender, sendResponse) {
            console.log(sender.tab ?
                        "from a content script:" + sender.tab.url :
                        "from the extension");
            if (request.type == "tab") {
                console.log("tab!");
                sendResponse({status: "ok"});
            }
        });
}

run();

Test JavaScript file (test.js):

'use strict';

run();

function run() {
    var url = window.location.href;

    // Error if no URI
    if (!url) {
        return 1;
    }

    var uriRe = /https:\/\/www\.google.*/;
    var reParse = uriRe.exec(url);
    if (!reParse) {
        return 2;
    }

    chrome.runtime.sendMessage({type: "tab"}, function(response) {
        console.log(response);
    });
}

Currently using Chrome 49.0.2623.112 (64-bit) on OSX.

Update: Attached a screenshot illustrating the occurrence of failures:

https://i.sstatic.net/CPyBx.png

To emphasize, the issue occurs intermittently (about 50% of the time), suggesting a potential unknown "race" condition complicating the matter.

Answer №1

Issue resolved: I had to toggle off and then back on all of my additional browser add-ons. Appears to be a glitch within Chrome.

Answer №2

Make sure to click on the top button and set the console in the extension environment

View image description here

The background only runs once. You should run it multiple times to check the result

Here is the code that is working fine:

chrome.tabs.onUpdated.addListener(
function(tabId,info,tab){
if(info.status=="complete")
console.log("complete")
chrome.tabs.sendMessage(tabId, {greeting: "inupdate"}, function(response) {
console.log(response);
});
}
)

Answer №3

I recently faced a similar issue. When I typed "chrome.runtime" in the console and expanded the object, I found only one function instead of multiple functions. Specifically, chrome.runtime.onMessage was undefined.

To resolve this, I went to the chrome://extensions page and removed the extension I was working on by clicking the "Remove" button. Then, I clicked on "Load unpacked" at the top of the page and selected the directory containing my extension. After doing this, chrome.runtime was fully populated, and my extension started working correctly. The reason behind this fix remains a mystery to me.

Answer №4

Perhaps the issue lies with the timeout function being utilized. Google actually offers a feature known as alarms that assists in scheduling code to execute at regular intervals or at specific times.

https://developer.chrome.com/apps/alarms

You might want to consider using that instead of timeout for your implementation.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Develop a cross-platform application using webpack for both web browsers and Node.js

I'm currently developing my first module, and the code is almost identical for both browser and node.js versions. The only variance lies in the use of XmlHttpRequest for the browser and the http module for node.js. Here's a sample code snippet t ...

Function necessary for successful data binding

The following code is causing an issue for me: <!DOCTYPE html> <html ng-app="m1"> <head> <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.7/angular.min.js"></script> </head> <body> ...

Does v-if cause the jquery clock picker to malfunction?

Here is my unique div where the clockpicker library functions correctly. <div class="input-group clockpicker"> <input type="text" class="form-control" value="18:00"> <span class="input-group-addon"> <span class ...

The addListener method in Google Maps iterates n times for a specific number of repetitions

When looking at the code below, the GetPropBasedOnRadius(); method loops for a certain number of times. I want to call that method only when the dragging event is completed. However, I am unsure how to do this. Any assistance on this matter would be great ...

Is the DOMContentLoaded event connected to the creation of the DOM tree or the rendering tree?

After profiling my app, I noticed that the event is triggered after 1.5 seconds, but the first pixels appear on the screen much later. It seems like the event may only relate to DOM tree construction. However, this tutorial has left me feeling slightly con ...

What could be the reason for v-model not functioning properly?

Embarking on my Vue.js coding journey, I am currently following a straightforward online tutorial. Utilizing the vue-cli, I kickstarted my application and crafted a basic component named Test.vue. Within this component lies a simplistic input control conne ...

The mouse movement event will not be triggered for every frame when a keyboard event occurs

When the mouse is moving in a browser, ideally the mousemove event should fire every frame. However, if a key is pressed or released (or repeated), the mousemove event stops firing for a frame or two. To test this behavior, you can use the code snippet bel ...

VueJS Error: Attempting to access a property that is undefined causing a TypeError (reading 'toLowerCase')

Whenever I attempt to filter and remove items from an array, everything works fine. However, when I try to add new items to the array, I encounter an error message that says "TypeError: Cannot read properties of undefined (reading 'toLowerCase'). ...

Synchronous loop in Javascript

Is there a method to execute codes asynchronously within a for loop? In this scenario, events ranging from day x to y need to be inserted into the calendar using a for loop. However, the current loop is taking too long, as it has to cover all the days fro ...

Show a message of 'no results found' when implementing a jQuery plugin for filtering items in a list

I recently implemented the 'Filtering Blocks' tutorial from CSS-Tricks to filter items by category on an events website I'm developing. While the filtering functionality works perfectly, I realized that there is no mechanism in place to sho ...

The AngularJS change event is not being activated

I am a beginner with angular js and I have implemented a bootstrap calendar in my application. However, I am facing an issue where the change event is not being triggered when the month changes, no matter where I place it within the code. Here is the snip ...

I attempted to upload an image using the Google Drive API, but encountered an error in the response

I am attempting to upload an image using the Google Drive API, but I encountered an error in the response message. The error reads as follows: "Failed to load resource: the server responded with a status of 403 ()" ...

Is it considered inefficient to import every single one of my web components using separate <script> tags?

Currently, I am in the process of developing a website with Express + EJS where server-side rendering is crucial. To achieve this, I am utilizing web components without shadow dom. Each page type (home, post, page) has its own EJS view. For instance, when ...

Is it possible to leverage both functions and variables within the ng-options expression in Angularjs?

I am faced with a situation where I have 2 select boxes. The first one is used to choose the user type (such as groups or individual), and the second one displays the options based on the selection made in the first box. I was wondering if it is possible t ...

Steer clear of displaying the latest model directly

Currently, I have a form for creating a new Model named Route. This form includes a select field called takeover, which displays all existing Routes for the user to choose from and establish a relationship with the selected Route. The issue I am facing is ...

The iteration of an ajax POST handler, looping endlessly

Attempting to implement a basic ajax submit handler for modifying a form as part of a lesson on CSRF vulnerabilities, but encountering an issue with the page looping. Below is the code snippet being worked on, inspired by http://api.jquery.com/jQuery.post/ ...

Create a roster of numbers that are multiples using a systematic approach

Is the following code a functional way to return multiples of 5? function Mul(start,array,Arr) { Arr[start]=array[start]*5; if(start>array.length-2){ return Arr; } return Mul(start+1,array,Arr); } var numbers =[1,2,3,4,5,6 ...

Keep track of the user's email address as they complete the form

I currently use a Google Form to gather information from employees who work in remote locations Emp No * Punch * Customer details / mode or travel All the data collected is stored in a Google spreadsheet structured as follows: Timestamp Emp No Punch ...

Can you provide instructions on executing package dependencies using yarn in the command line? For example, is there a command similar to npx tsc init for initializing a npm

When utilizing yarn, the node_modules folder is not present. Instead, dependencies are stored in a .yarn/cache folder. I attempted to use yarn dlx tsc init and npx tsc init, but they did not achieve the desired result. There are various development depend ...

When a button is clicked, retrieve information from a server using Node.js

In my front end code, I have a scenario where upon clicking a button, I need to retrieve specific data from the node server to populate a map on the client side. The map can be viewed at: "http://localhost:8080/" Here's how I'm making the reques ...