"Error: An unexpected error occurred" when calling browser.storage.local.set

I’ve just started delving into Firefox extension development. Unfortnately I’ve already encountered an unusual error that I cannot find a solution to.

I’m trying to store data into localStorage in the background. When calling
browser.storage.local.set(), no matter what the input it, I get a rejected promise with the reason “Error: An unexpected error occurred”.

I’ve even tried just using the following snippet copied straight fron the MDN documentation on this method, and the result is the same.

let monster = {
  name: "Kraken",
  tentacles: true,
  eyeCount: 10
}

let kitten = {
  name: "Moggy",
  tentacles: false,
  eyeCount: 2
}

// store the objects
browser.storage.local.set({kitten, monster})

I’m using Firefox 111.0.1, the manifest is v2, storage permission is added and I also tried adding unlimitedStorage just in case.

Anyone have a clue on what’s going on?

Could you please try to visit this storage test page?
https://firefox-storage-test.glitch.me/
(the test takes about 10 seconds and you should see “Storage is working.” message)

Can you post the source code for the entire extension? Including manifest.json

@juraj.masiar storage seems to be working OK

@hans_squared

manifest.json

{
    "manifest_version": 2,
    "name": "Test Monitor",
    "version": "1.0.0",
    "description": "Does stuff",
    "icons": {
        "48": "icons/Test-icon.png"
    },
    "content_scripts": [
        {
            "matches": [
                "https://*"
            ],
            "js": [
                "content-scripts/content-script.js"
            ],
            "run_at": "document_idle"
        }
    ],
    "background": {
        "scripts": [
            "background/background.js",
            "utilities/timing-utilities.js"
        ],
        "persistent": true
    },
    "browser_action": {
        "default_icon": "icons/Test-icon.png",
        "default_title": "Test Monitor",
        "default_popup": "popup/index.html"
    },
    "permissions": [
        "webNavigation",
        "storage",
        "activeTab",
        "tabs"
    ]
}

background.js

browser.tabs.onUpdated.addListener((tabId, changeInfo, tab) => {
    console.log('bg - onUpdated - tabId: ', tabId, ' changeInfo: ', changeInfo, ' tab: ', tab);
    if (changeInfo.url) {
        browser.tabs.sendMessage(tabId, { action: 'urlChanged', url: tab.url });
        console.log('tab update message sent!');
    }
});
browser.runtime.onMessage.addListener((request, sender, sendResponse) => {
    console.log('bg - onMessage - request: ', request);

    switch (request.action) {
        case 'registerUrlChangeHandler':
            browser.tabs.query({ active: true, currentWindow: true }, (tabs) => {
                browser.tabs.sendMessage(tabs[0].id, { action: 'urlChanged', url: tabs[0].url });
                console.log('bg - registerUrlChangeHandler response sent');
            });
            break;

        case 'itemDatasetInit':
            inititemDataset(request);

            break;

        case 'itemPriceUpdate':

            break;
    }
});

async function inititemDataset(request)
{
    try {
        let storeditems = await browser.storage.local.get("items");

        console.log('retrieved items from storage: ', storeditems);
        
        let items = request.data.reduce((sum, current) => {
            if(sum.hasOwnProperty(current.id))
            {
                sum[current.id].push([ Date.now(), current.price ]);
            }
            else
            {
                sum[current.id] = [[ Date.now(), current.price ]];
            }
            return sum;
        }, storeditems);
        
        // store the objects
        await browser.storage.local.set({ storeditems });

    } catch (error) {
        console.log('error:', error);
    }
}

I can’t reproduce the problem.

The only bug I can find is that you aren’t destructuring storeditems.
And using forEach() instead of reduce() would probably be simpler.

let { items } = await browser.storage.local.get("items");
if (items === undefined) {
	items = {};
}

[{id: 0, price: 10}, {id: 1, price: 11}, {id: 2, price: 12}].forEach(current => {
	if (items[current.id] === undefined) {
		items[current.id] = [];
	}
	items[current.id].push([Date(), current.price]);
});

await browser.storage.local.set({ items });

“https://*” is an invalid match pattern, because there’s no path.
On my computer, Firefox refuses to load the extension:

Extension is invalid

Reading manifest: Error processing content_scripts.0.matches.0: Value "https://" must either: be one of ["<all_urls>"], must either [match the pattern /^(https?|wss?|file|ftp|*)://(*|*.[^/]+|[^/]+)/.$/, or match the pattern /^file:///.$/], or match the pattern /^resource://(*|*.[^/]+|[^/]+)/.$|^about:/

@hans_squared I’ve modified manifest.json URL’s slightly for security reasons, and I’ve apparently made it invalid. Apologies for that.

That said, the error is gone after Firefox update to 112.0!