Error: Missing host permission for the tab

I’m doing some initial testing, for Manifest v3.
When I’m trying to executeScript from background, I get “Error: Missing host permission for the tab”
I have enabled scripting and activeTab, and everything I can think of.
What am I missing?


  "name": "Hello, World!",
  "version": "1.0",
  "manifest_version": 3,
  "background": {
    "scripts": ["background.js"]
  "permissions": [
  "host_permissions": ["<all_urls>", "*://*/*"],
  "action": {},
  "content_security_policy": {
	    "extension_pages": "script-src 'self'; object-src 'self'"


  browser.runtime.onInstalled.addListener(async () => {
  let url = browser.runtime.getURL("hello.html");
  let tab = await browser.tabs.create({ url });
  try {
    await browser.scripting.executeScript({
      target: {
      func: () => {
  } catch (err) {
    console.error(`failed to execute script: ${err}`);

It seems that all host permissions must be explicitly granted by user in Firefox MV3 (for now). Similarly how Safari is doing (and I really don’t like it). And I think Chrome wanted to do something like that as well but I don’t see it now anywhere…

Anyway, see here more info:

1 Like

Now I understand the issue, but I don’t see where I can set those permission manually, as everything is already activated:

Actually, there may be another issue. Chrome doesn’t allow executing (injecting) scripts on extension pages, not even your own.

I’m pretty sure this was possible in Firefox MV2, so maybe it’s not anymore in MV3.

Well, what I’m exactly looking for is to inject inside a (any) browser page.
I already have my devtool extension that works in MV2.
Now I need to figure out how to solve this permission problem with MV3.


Well, foreign extension pages are taboo :slight_smile:, there is no injecting there no matter what.

And if you can’t inject into your own page, you could use “dynamic import” feature. That’s what I use in Chrome, I send a message to the tab and when it receives it, it will call “import('some_file.js')”. But that works only when injecting a file.