[EDITED] Error: Permission denied to access property "then"

I have a working mv3 chrome extension. When the content script receives a message it dispatches a custom event. The custom event is handled by a class that is injected in the target page window.

Inject the class:

window.test = new Test()

Dispatch event (in content script):

document.dispatchEvent(
    new CustomEvent('myevent', { detail: data })
)

Handle the event (in Test class):

return new Promise(resolve => {
  const listener = (event: any) => {
    document.removeEventListener('myevent', listener)
    console.log('resolving', event.detail)
    resolve(event.detail)
  }
  document.addEventListener('myevent', listener)
})

In chrome I have no problems, but in firefox the promise doesn’t get resolved. I get the ‘resolving’ print statement, but then the error occurs.

Any idea what could be causing the issue? Is it some firefox setting? Could it be my manifest?
Chrome

"permissions": ["tabs", "background", "storage"],
  "action": {
    "default_popup": "index.html",
    "default_icon": "icon_128.png"
  },
  "content_scripts": [
    {
      "matches": ["<all_urls>"],
      "js": ["content.js"],
      "run_at": "document_start"
    }
  ],
  "background": {
    "service_worker": "background.js",
    "type": "module"
  },

Firefox

"permissions": ["tabs", "scripting", "storage"],
  "action": {
    "default_popup": "index.html",
    "default_icon": "icon_128.png"
  },
  "content_scripts": [
    {
      "matches": ["<all_urls>"],
      "js": ["content.js"]
    }
  ],
  "background": {
    "scripts": ["background.js"],
    "type": "module"
  },

The problem apparently was that the content of event.detail was an object.
To solve it, instead of dispatching the event with { detail: data } I dispatched it with { detail: JSON.stringify(data) }. Then this can be parsed in the listener and the promise resolves correctly resolve(JSON.parse(event.detail)).

1 Like

not sure if it applies to you, but this sounds exactly like mine problem - with sharing data between content script and page script - you have to use cloneInto() to allow page script access objects from content script context, if you want to use promise or encode to json, remember to use cloneFunctions: true.

cloneInto()

Whole guide:

(sorry for necro)