How to "Replace Content of SmartObject"

I’m trying to write a script, which allows me to replace the content of a smartObject (image).
I’m using batchPlay to achieve this, but I’m facing certain issues.

My approach:

  1. Record action
  2. In Actions menu, click on options menu on top right with 3 lines.
  3. Copy as Javascript. The code I get is the following
async function replace() {
    let result;
    let psAction = require("photoshop").action;

    let command = [
        // Relink to File
        {"_obj":"placedLayerRelinkToFile","layerID":2,"null":{"_kind":"local","_path":"/Users/david/Desktop/images/image3.jpg"}}
    ];
    result = await psAction.batchPlay(command, {});
}

async function runModalFunction() {
    await require("photoshop").core.executeAsModal(replace, {"commandName": "Action Commands"});
}

await runModalFunction();

This doesn’t work for me for some reason. It works with other commands, such as “hide”, “move”, “duplicate”, but relinking the content doesn’t work.

The error I get from alchemist is: “Invalid file token used”

Any one faced a simliar issue and knows how to fix this?

You need to create a session token: check this topic, it maybe the same idea you are looking for.

https://forums.creativeclouddeveloper.com/t/how-do-you-place-an-image-from-the-local-file-system-using-batchplay/2407/16

In version 24.2 or higher of Photoshop this should work

async function replace() {
    let result;
    let psAction = require("photoshop").action;
    const fs = require('uxp').storage.localFileSystem;
    const myfile = await fs.getEntryWithUrl("file:/Users/david/Desktop/images/image3.jpg"); 
    const token = fs.createSessionToken(myfile);

    let command = [
        // Relink to File
        {"_obj":"placedLayerRelinkToFile","layerID":2,"null":{"_kind":"local","_path":token}}
    ];
    result = await psAction.batchPlay(command, {});
}

async function runModalFunction() {
    await require("photoshop").core.executeAsModal(replace, {"commandName": "Action Commands"});
}

await runModalFunction();

Add this to your manifest.json file

"minVersion": "24.2.0",
"localFileSystem": "fullAccess",

Thank you very much for your answer. Indeed this works.

One part I still struggle with is properly targeting my layer. I can make it work if I select the layer in photoshop and then run my script. This works, because of “This property (_target) is sometimes omitted. If omitted, the command operates on a default element. The default element is typically the object that is active in the UI.” as described in this part of the script.

If I use the parameter in my command

            "_options": {
               "dialogOptions": "dontDisplay"
            }

I get the error in photoshop “The command “Relink to File” is not currently available.

I just can’t make it work with a layerID or a target. I tried several variations of them, but it doesn’t seem to work. Any idea why? Something worth pointing out I’m writing a script and not a plugin. This might cause these errors somehow.

I found a solution by first using the “select” action and then replacing my image. But directly targeting didn’t work for me for some reason.