BatchPlay move does not work as expected

Moving layers using batchPlay does not work in all cases. Below are two samples of code.

  • First one is always working example where move is called on a separate batchPlay()
  • Second one is all-in-one-go. There select actions happen as expected, but move actions are never executed. And to make it stranger… If you repeat same batchPlay() call again, then it works. And it works until you delete all these generated groups. Delete these groups and again first call fails to move layer, but every consecutive works fine

NB: Make sure you don’t have only a single background layer, because selectNoLayers fails and prevent script execution. Have at least one non-background layer


Works every time:

require("photoshop").action.batchPlay(
    [
        {
            "_obj": "selectNoLayers",
            "_target": [{"_ref": "layer", "_enum": "ordinal", "_value": "targetEnum"}]
        },
        {
            "_obj": "make",
            "_target": [{"_ref": "layerSection"}],
            "using": {"_obj": "layerSection", "name": "Group"}
        },
        {
            "_obj": "make",
            "_target": [{"_ref": "layer"}],
            "using": {"name": "Bottom, Should end at the top"}
        },
        {
            "_obj": "make",
            "_target": [{"_ref": "layer"}],
            "using": {"name": "Lower"}
        },
        {
            "_obj": "make",
            "_target": [{"_ref": "layer"}],
            "using": {"name": "Upper"}
        },
        {
            "_obj": "select",
            "_target": [{"_ref": "layer", "_enum": "ordinal", "_value": "backwardEnum"}]
        },
        {
            "_obj": "select",
            "_target": [{"_ref": "layer", "_enum": "ordinal", "_value": "backwardEnum"}]
        }
    ],
    {
        "synchronousExecution": true,
        "modalBehavior": "execute",
        "historyStateInfo": {
            "name": "Create test layers",
            "target": {"_ref": "document", "_enum": "ordinal", "_value": "targetEnum"}
        }
    }
);

require("photoshop").action.batchPlay(
    [
        {
            "_obj": "move",
            "_target": [{"_ref": "layer", "_enum": "ordinal", "_value": "targetEnum"}],
            "to": {"_ref": "layer", "_enum": "ordinal", "_value": "next"}
        },
        {
            "_obj": "move",
            "_target": [{"_ref": "layer", "_enum": "ordinal", "_value": "targetEnum"}],
            "to": {"_ref": "layer", "_enum": "ordinal", "_value": "next"}
        }
    ],
    {
        "synchronousExecution": true,
        "modalBehavior": "execute",
        "historyStateInfo": {
            "name": "Move test layer",
            "target": {"_ref": "document", "_enum": "ordinal", "_value": "targetEnum"}
        }
    }
);

Never works on first call when still no generated layers exist:

require("photoshop").action.batchPlay(
    [
        {
            "_obj": "selectNoLayers",
            "_target": [{"_ref": "layer", "_enum": "ordinal", "_value": "targetEnum"}]
        },
        {
            "_obj": "make",
            "_target": [{"_ref": "layerSection"}],
            "using": {"_obj": "layerSection", "name": "Group"}
        },
        {
            "_obj": "make",
            "_target": [{"_ref": "layer"}],
            "using": {"name": "Bottom, Should end at the top"}
        },
        {
            "_obj": "make",
            "_target": [{"_ref": "layer"}],
            "using": {"name": "Lower"}
        },
        {
            "_obj": "make",
            "_target": [{"_ref": "layer"}],
            "using": {"name": "Upper"}
        },
        {
            "_obj": "select",
            "_target": [{"_ref": "layer", "_enum": "ordinal", "_value": "backwardEnum"}]
        },
        {
            "_obj": "select",
            "_target": [{"_ref": "layer", "_enum": "ordinal", "_value": "backwardEnum"}]
        },
        {
            "_obj": "move",
            "_target": [{"_ref": "layer", "_enum": "ordinal", "_value": "targetEnum"}],
            "to": {"_ref": "layer", "_enum": "ordinal", "_value": "next"}
        },
        {
            "_obj": "move",
            "_target": [{"_ref": "layer", "_enum": "ordinal", "_value": "targetEnum"}],
            "to": {"_ref": "layer", "_enum": "ordinal", "_value": "next"}
        }
    ],
    {
        "synchronousExecution": true,
        "modalBehavior": "execute",
        "historyStateInfo": {
            "name": "Create test layers",
            "target": {"_ref": "document", "_enum": "ordinal", "_value": "targetEnum"}
        }
    }
);

I really don’t want to split to separate calls, because it makes a separate history state.
This is a simplified example to reproduce the issue - I use a more complex structure with multi-level groups, so I need to do some layer moving after creating them.

I had the same thing and I have to split them. I couldn’t find a work-around. I think I posted about this several months ago as well.

For the history states,I wish there was an equivalent to the suspend history in JSX. It would be nice to have 1 history state for an entire function. There is just no way in many cases to put everything into 1 batch play. Not just because of this issue, but if you need to run some calculations between batch plays then you need to split them too.

I saw it mentioned in some topic, that devs are working on a solution to wrap multiple actions to a single history state. I hope this comes sooner than later - would make things so much easier