I tested this on Photoshop 2026 on Windows as well, and my results seem to point in the same direction.
As @Jarda said, -128 means “user cancelled”, and I also tried the interactive: true suggestion.
I tested the same duplicate command inside executeAsModal from different contexts:
- Directly from the plugin UI, without a dialog →
works
- From a modeless dialog,
dialog.show() →
works
- From a modal dialog,
dialog.showModal() →
[{ _obj: "error", result: -128 }]
showModal() + executeAsModal(fn, { interactive: true }) →
still -128
So the issue seems to be specifically related to showModal(), not to running batchPlay from a dialog in general.
A modeless dialog opened with show() can run document-modifying batchPlay commands inside executeAsModal correctly. In my tests, duplicating the document repeatedly from a show() dialog worked without errors.
interactive: true does not seem to fix the showModal() case. My interpretation is that showModal() blocks Photoshop’s UI in a way that prevents Photoshop from granting the modal scope to executeAsModal in the first place.
interactive: true may affect the behavior once the modal scope has already been granted, but it does not seem to help if that scope cannot be entered.
So the workaround seems to be: use a modeless show() dialog for any UI that needs to modify the document.
const { core, action } = require("photoshop");
const dlg = document.createElement("dialog");
dlg.innerHTML = `<button id="dup">Duplicate</button>`;
document.body.appendChild(dlg);
dlg.querySelector("#dup").addEventListener("click", async () => {
await core.executeAsModal(async () => {
await action.batchPlay([
{
_obj: "duplicate",
_target: [
{
_ref: "document",
_enum: "ordinal",
_value: "first"
}
],
_options: {
dialogOptions: "dontDisplay"
}
}
], {});
}, {
commandName: "Duplicate document"
});
});
dlg.show(); // Works with a modeless dialog
// dlg.showModal(); // Returns -128
@SandeepSharma , is this showModal() + executeAsModal behavior intended in Photoshop 2026, or could it be a regression from Photoshop 2025?
Hope this helps.