Prior to PS 23.4.1, we could just use the following descriptor to convert between color spaces:
{
_obj: "convertColorToSpace",
_target: { _ref: "application" },
color,
colorSpace: {
_enum: "colorSpace",
_value: colorSpace
}
After the update, it now results in
convertColorToSpace may modify the state of Photoshop. Such events are only allowed from inside a modal scope
Is it a final decision that this now has to happen inside a modal scope, or did that happen on accident?
I don’t think it modifies the PS state (similar to a getter) 
Interesting, I just wrap all my code in a ExecuteAsModal model and don’t bother
as I am still learning coding by doing 
Yes, that what I had to do here as a fix. However, it’s not really pretty, since executeAsModal
runs the code you pass in the callback and returning something from a callback (to the outer function) requires you to return a promise instead which you can resolve in the callback. Here’s the new code:
async function convertColorSpace(color, colorSpace) {
return new Promise((resolve) => {
photoshop.core.executeAsModal(async() => {
resolve(await photoshop.action.batchPlay([
{
_obj: "convertColorToSpace",
_target: { _ref: "application" },
color,
colorSpace: {
_enum: "colorSpace",
_value: colorSpace
}
}
],{})[0].color)
})
})
}
As a consequence of that, I had to also make all other helper functions async that called this function and so on…