How To Get BatchPlay To Work With API 2

Thanks, I had not seen that example before. Just tried it and it works great.

Hm, I really hope this will not happen too quickly. Feels like I’m spending more time migrating plugins between different versions / technologies than actually building new plugins :zipper_mouth_face: (at first CEP → UXP and now API1 → API2… what will come next?)

I think it is on this page… but the page now gives a 404 error. The 404 errors have been pretty common on the “stage” documents. I need to start taking screenshots when I have the chance.

This page that references it is still up

In order to allow plugin developers to gradually move to the new model, Photoshop 2022 supports both the original and the new JavaScript modes. A plugin uses the apiVersion field to specify which model it uses.

  • apiVersion of 1 signifies that the plugin is using the original Photoshop 2021 implementation.
  • apiVersion of 2 signifies that the plugin is using the new modal JavaScript feature.

With the introduction of apiVersion = 2, the original implementation is formally deprecated, and support for apiVersion 1 will be removed in a future major update to Photoshop. As such a number of new features are only available for apiVersion 2 plugins. apiVersion 2 only features include: new DOM v2, support for suspend and resume of multiple history states at the same time.

Photoshop Product specific manifest (

1 Like

That doesn’t tell us anything about whether or not modeless Photoshop dialog interaction will be supported in API 2. That is a huge deal for some plugins if that functionality gets dropped. I really wish we had some clarification on this.

Does it all mean that if I’m using api 2 and batch play, and for example the batch play will ask user to set the radius of Gaussian blur, it will not work?

That was true when I replied back in October. Last I checked a couple weeks ago, it was fixed for the case where you were just showing 1 dialog per executeAsModal function. However, if you do 2 steps that show the dialog anywhere within the same executeAsModal function then Photoshop would still freeze on the second dialog. Also, if you use a showAlert anywhere after the show dialog in the executeAsModal function then it was freezing too.

I put in a bug report on this in the pre-release group but there hasn’t been any updates to the bug post. However, I haven’t actually tested in a couple of weeks in the latest beta release so there is a chance it has been fixed since I last checked and the bug post wasn’t updated. I’m not sure how often the bug posts actually get updated.

Thank you, I’ve tested with one dialog so far and it works fine.
I’m wondering if there is an option to assign custom dialog to the const that will ask user to input the number.

Use case is - I want to create custom save option and dialog / prompt will ask user to select long edge of the final JPG (for resize).


If you mean something like this screenshot then yes, that can be done. You need to use a modal dialog. Download the “Kitchen Sink” sample plugin from Adobe and look at that. There is a modal dialog example in it. It’s is too much to explain in a post but it’s not too difficult to do.

1 Like

Isn’t Kitchensink still on API v1?

Perfect, thank you. I’ll take a look at this example.

I think so. However the modal dialogs work the same. I don’t recall having to change anything with those when converting to API 2.

1 Like

I don’t see modal dialog example in Kitchen sing sample :confused: would you be so kind to share code for the dialog with user input?

Thank you!

Here’s a dialog example (dynamically built in JS) from Kerry.

It is because you have the modalBehavior option set to “fail”. It needs to be “execute” or default. Just use {} for the batch play options and it will set them to default.

Say this louder for the people in the back! If you don’t pass in empty brackets, batchplay refuses to run at all, which is in direct opposition to the official documentation example.

incorrect example:

In addition, is there any way to see when a batchplay fails, or why it fails? There is no messaging in the UXP Dev Tool log, and combined with the sometimes-false official documentation, it requires pure-luck to figure out what is going on.

There’s definitely an error that returns “batchPlay missing second parameter”, but I agree its usage is ambiguous at best in the documentation.

Where do you see this error? It definitely does not appear in the UXP Developer Tool log.
I have a duplicate layer batchplay call that works fine. I took out the brackets and preceding comma, saved and reloaded the plugin, clicked the button, nothing happens and no errors appear.
I have both error and warn levels turned on.

You need to wrap your batchPlay call in a try/catch block:

const batchplayError = async () => {
  const { core } = require("photoshop");
  const batchPlay = require("photoshop").action.batchPlay;

  return core.executeAsModal(async () => {
    try {
      return await batchPlay(
          // ...actionDescriptors array
        // {} Second argument commented out
    } catch (error) {

Screenshot 2023-02-25 193717

I guess try blocks don’t catch every error inside them in javascript? I was using a function that wraps executeAsModel to catch any errors and then passing the async function that contains the batchplay call into the error-catching function. I’m almost positive that in python, for example, any exception hit in the block would be caught.

But that does not appear to be the case in this language, because as soon as I used your version, which only wraps the batchplay call, I finally got some logs.


You would be correct in thinking that any exception thrown within a try block should be passed to the catch:

“If any statement within the try-block (or in a function called from within the try-block) throws an exception, control is immediately shifted to the catch-block.” ~ MDN try/catch article

I’ve encountered this behaviour in UXP before, but I never got around to testing further. If memory serves correct it seemed like executeAsModal blocks it. I’m now just in the habit of always wrapping any batchPlay calls directly!

1 Like