Inconsistent behavior when switching both layer and tool from a single UXP plugin button

I’m developing a Photoshop UXP panel that allows users to quickly switch between two layers and set the corresponding tool (e.g. Clone Stamp for one, Mixer Brush for the other).
Expected behavior:

Click one button → switches to target layer and sets the correct tool

What I’ve tried:

Switching layer via batchPlay inside executeAsModal

Switching tool via:

    A second executeAsModal call

    setTimeout and async delays

    app.currentTool (DOM-based switch)

    Combined batchPlay calls inside a single executeAsModal

Layer and tool switches in separate buttons

Introducing artificial pauses and dummy commands to reset Photoshop state

Observed issues:

When layer and tool switching are triggered in sequence (even with delays), Photoshop frequently enters a broken state:

    Tool switch fails silently

    Keyboard shortcuts for tools stop working entirely

    Photoshop doesn’t recover until another native modal is opened (e.g. Image Size)

No errors appear in the console

This happens even when tool switching is separated into a second button click, and the layer switch alone seems to trigger it

Has anyone found a reliable, UXP-compliant way to trigger both layer and tool switching from a single button press — without triggering Photoshop’s broken modal state or disabling keyboard input?

Yes. I have this working in on one of the panels in production and have no issues. You can do that in single modal call. Timeout work only within your plugin. It ignores other plugin modal states and also PS modal dialogs.

It sounds like PS enters modal state and does not leave it. That would block keyboard shortcuts.

Also, it can quite often have errors without letting you know. Errors not shown - How to workaround non-existent `onunhandledrejection`

Yes. Probably tool switch modal is being executed while layer switch modal isn’t finished yet

Thanks, Jarda — really appreciate the insight.

Could I ask for a bit more detail on how you structure the executeAsModal call?

In my case, I’m trying to switch to a specific layer by name (using batchPlay) and then switch to a specific tool (e.g. cloneStampTool). I’ve tried combining those two operations in a single executeAsModal, but it seems like Photoshop sometimes enters that stuck modal state — the tool switch silently fails, and keyboard shortcuts become unresponsive until I manually open a native modal like Image Size.

I’d love to understand:

  • Are both select commands (layer + tool) part of the same batchPlay array?
  • Do you include both events inside the same object, or two objects in sequence?
  • Are there any special _options or flags that make the tool switch succeed reliably inside executeAsModal?

If you’re able to share even a stripped-down example of the structure, it would be incredibly helpful.

Thanks again — this has been the one blocker preventing a clean implementation!