Skip to content

Conversation

@himabindu-1614
Copy link

This PR adds clarification to the Return value section of the scripting.executeScript() documentation.

The issue (#41916) points out that users may think Promises cannot be returned, since the structured-clone documentation doesn’t mention them. This update explains that Firefox awaits returned Promises and uses their resolved values, matching Chrome’s behavior.

Related issues

Fixes #41916

@himabindu-1614 himabindu-1614 requested a review from a team as a code owner November 13, 2025 17:15
@himabindu-1614 himabindu-1614 requested review from rebloor and removed request for a team November 13, 2025 17:15
@github-actions github-actions bot added Content:WebExt WebExtensions docs size/xs [PR only] 0-5 LoC changed labels Nov 13, 2025

The script result must be a [structured cloneable](/en-US/docs/Web/API/Web_Workers_API/Structured_clone_algorithm) value in Firefox or a [JSON-serializable](/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify#description) value in Chrome. The [Chrome incompatibilities](/en-US/docs/Mozilla/Add-ons/WebExtensions/Chrome_incompatibilities) article discusses this difference in more detail in the [Data cloning algorithm](/en-US/docs/Mozilla/Add-ons/WebExtensions/Chrome_incompatibilities#data_cloning_algorithm) section.

**Note:** If the injected script returns a `Promise`, Firefox will automatically await the promise and use its resolved value as the result. Although the structured clone algorithm does not explicitly list Promises as cloneable, the `executeScript()` API handles Promises by awaiting them before applying structured cloning. This behavior matches Chrome’s implementation, where returned Promises are also awaited.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[mdn-linter] reported by reviewdog 🐶

Suggested change
**Note:** If the injected script returns a `Promise`, Firefox will automatically await the promise and use its resolved value as the result. Although the structured clone algorithm does not explicitly list Promises as cloneable, the `executeScript()` API handles Promises by awaiting them before applying structured cloning. This behavior matches Chromes implementation, where returned Promises are also awaited.
**Note:** If the injected script returns a `Promise`, Firefox will automatically await the promise and use its resolved value as the result. Although the structured clone algorithm does not explicitly list Promises as cloneable, the `executeScript()` API handles Promises by awaiting them before applying structured cloning. This behavior matches Chrome's implementation, where returned Promises are also awaited.


The script result must be a [structured cloneable](/en-US/docs/Web/API/Web_Workers_API/Structured_clone_algorithm) value in Firefox or a [JSON-serializable](/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify#description) value in Chrome. The [Chrome incompatibilities](/en-US/docs/Mozilla/Add-ons/WebExtensions/Chrome_incompatibilities) article discusses this difference in more detail in the [Data cloning algorithm](/en-US/docs/Mozilla/Add-ons/WebExtensions/Chrome_incompatibilities#data_cloning_algorithm) section.

**Note:** If the injected script returns a `Promise`, Firefox will automatically await the promise and use its resolved value as the result. Although the structured clone algorithm does not explicitly list Promises as cloneable, the `executeScript()` API handles Promises by awaiting them before applying structured cloning. This behavior matches Chrome’s implementation, where returned Promises are also awaited.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it possible to simplify like this?

Note

If the injected script returns a Promise, the executeScript() API awaits the Promise then applies structured cloning to the result. This behavior matches Chrome's implementation, where the returned Promise is awaited.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I’ve updated the note with the simplified wording you suggested. Thank you! 😊

@himabindu-1614 himabindu-1614 force-pushed the docs/fix-41916 branch 2 times, most recently from fc24357 to 7f86adc Compare November 13, 2025 17:59

### Return value

A [`Promise`](/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that fulfills with an array of `InjectionResult` objects, which represent the result of the injected script in every injected frame.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Replace hard-coded link with a macro.

Suggested change
A {{JSxRef("Promise")}} that fulfills with an array of `InjectionResult` objects, which represent the result of the injected script in every injected frame.


The script result must be a [structured cloneable](/en-US/docs/Web/API/Web_Workers_API/Structured_clone_algorithm) value in Firefox or a [JSON-serializable](/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify#description) value in Chrome. The [Chrome incompatibilities](/en-US/docs/Mozilla/Add-ons/WebExtensions/Chrome_incompatibilities) article discusses this difference in more detail in the [Data cloning algorithm](/en-US/docs/Mozilla/Add-ons/WebExtensions/Chrome_incompatibilities#data_cloning_algorithm) section.

**Note:** If the injected script returns a Promise, the `executeScript()` API awaits the Promise then applies structured cloning to the result. This behavior matches Chrome's implementation, where the returned Promise is awaited.
Copy link
Collaborator

@dotproto dotproto Nov 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change is the only place where we describe injected scripts a having a 'return value.' For consistency, we should instead use a phrase like "script result" or "result of the injected script."

Also, MDN note blocks use standard GFM syntax (docs).

Suggested change
**Note:** If the injected script returns a Promise, the `executeScript()` API awaits the Promise then applies structured cloning to the result. This behavior matches Chrome's implementation, where the returned Promise is awaited.
> [!NOTE]
> If the script result is a Promise, the `executeScript()` call awaits the resolution of the Promise before copying the settled value.

NOTE: This suggestion is mutually exclusive with this suggestion. If we do not use this suggestion, this line should be removed.


Chrome does not support the `error` property yet (see [Issue 1271527: Propagate errors from scripting.executeScript to InjectionResult](https://crbug.com/1271527)). As an alternative, runtime errors can be caught by wrapping the code to execute in a try-catch statement. Uncaught errors are also reported to the console of the target tab.

The result of the script is the last evaluated statement, which is similar to the results seen if you executed the script in the [Web Console](https://firefox-source-docs.mozilla.org/devtools-user/web_console/index.html) (not any `console.log()` output). For example, consider a script like this:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This paragraph feels to me like a more natural place to mention Promise handling.

Suggested change
The result of a script is the value produced by the last evaluated statement. If the last statement produces a Promise, the result is the settled value of that Promise. This is similar to the results seen if you execute the script in the [Web Console](https://firefox-source-docs.mozilla.org/devtools-user/web_console/index.html) (excluding any `console.log()` output). For example, consider a script like this:

NOTE: This suggestion is mutually exclusive with this suggestion.

Comment on lines +64 to +75
The result of the script is the last evaluated statement, which is similar to the results seen if you executed the script in the [Web Console](https://firefox-source-docs.mozilla.org/devtools-user/web_console/index.html) (not any `console.log()` output). For example, consider a script like this:

```js
let foo = "my result";
foo;
```

Here the results array contains the string `"my result"` as an element.

The script result must be a [structured cloneable](/en-US/docs/Web/API/Web_Workers_API/Structured_clone_algorithm) value in Firefox or a [JSON-serializable](/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify#description) value in Chrome. The [Chrome incompatibilities](/en-US/docs/Mozilla/Add-ons/WebExtensions/Chrome_incompatibilities) article discusses this difference in more detail in the [Data cloning algorithm](/en-US/docs/Mozilla/Add-ons/WebExtensions/Chrome_incompatibilities#data_cloning_algorithm) section.

**Note:** If the injected script returns a Promise, the `executeScript()` API awaits the Promise then applies structured cloning to the result. This behavior matches Chrome's implementation, where the returned Promise is awaited.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is out of scope for this PR, but IMO we should move this block (lines 64-75) into it's own sub-header under the main description for organization and linking purposes.

@dotproto
Copy link
Collaborator

In my last review I provided two mutually exclusive suggestions on how we could update the article to incorporate information about promise handling. I think I prefer updating the paragraph that defines script result rather than adding a new note. @rebloor, what do you think?

@rebloor
Copy link
Contributor

rebloor commented Nov 17, 2025

Thenks @dotproto. @himabindu-1614 I agree with @dotproto that the paragraph that defines script result is a more appropriate change.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Content:WebExt WebExtensions docs size/xs [PR only] 0-5 LoC changed

Projects

None yet

Development

Successfully merging this pull request may close these issues.

missleading / missing context to the return value of scripting.executeScript()

3 participants