Script Bug Report & Feature Request for Tagging System

Hello, I'm a user who enjoys using Directory Opus 13. I'm writing to report some bugs I've encountered and to suggest a new feature.


1. Bug Report: Core Scripting Objects/Methods are Inaccessible

While creating a JScript Add-in, I discovered that several core scripting functionalities are not working.

The Problem: When calling the following functions within a script, it fails with the error "Object doesn't support this property or method (0x800a01b6)" or "'undefined' is null or not an object (0x800a138f)".

  • Dialogs: scriptCmdData.func.Dlg.GetString() or GetMultiChoice()
  • File System Access: DOpus.FSUtil()
  • Clipboard Control: DOpus.SetClip()

This makes it impossible to create most useful scripts that require any form of UI interaction or file access.

Additional Bug: Furthermore, there seems to be a specific issue with the SetAttr command, even when used as a simple User Command.

  • SetAttr META "comment:test" -> Works correctly.
  • SetAttr META "keywords:+test" -> Fails with a "Meta parsing error."
  • However, editing keywords manually via the GUI in the metadata pane works perfectly fine.

This suggests a specific bug in how the SetAttr command handles the keywords field.


2. Feature Request: Lightroom-style Tag (Keyword) Editor

I'd like to suggest an improvement to the current keyword editing workflow, inspired by Adobe Lightroom's convenient tagging system.

Desired Functionality:

  1. Keyword Suggestions & Autocomplete: When I start typing in the 'Keywords' field of the metadata pane, a dropdown list should appear, suggesting keywords that match my input. This list would be populated from a predefined list or from existing keywords.
  2. Click to Add: I could then simply click on a keyword from the suggestion list to add it to the file.
  3. External List File Integration: It would be incredibly useful if this keyword suggestion list could be sourced from an external .txt file (e.g., D:\MyTags.txt). This would allow users to easily manage their master keyword list without having to edit a script.

Implementing these features would be a massive help for organizing photos and files. Thank you for your time and for this great software.

Or is there a similar feature or a manual that I can refer to as a manual? I coded with Ai, but I surrendered both Chet GPT and Gemini. So I'm very sad. If you have a script or manual that does a similar function, please let me know. Thank you.

1 Like

Please Ask one question per thread

For the questions about script code, please provide details of how you are calling the objects and running the commands, and which files they're being run on if applicable.

The scripting objects definitely work in general. If they didn't, half the script son the forum would fail.

1 Like

I wonder if there's a connection... :thinking:

2 Likes

First of all, I'm sorry for making you confused
I used it for the first time this time, and I usually send reports like this by e-mail, so I'm sorry that it's proceeded without a thread topic
First of all, I have a hobby of changing a lot of Tag or metadata, and it was so annoying to do this one by one, so I wanted to make it using scripts
But I didn't know how to code, so I thought of using Ai, so I asked for this coding, but I didn't succeed in the end with many errors
In the end, AI even made a document like that to ask the developer and told him to ask here

Originally, the goal was to create a template in which tags or information are clicked within the Directory Opus itself, but since it failed, I tried to import and create an external text file, but in the end, it failed

If this doesn't work out with a script, I was going to make that function request, so there were two in the same thread

If the command is too complicated, can I do this as a feature request?

And below, it's a code created by AI. We've been working together almost all day, but Ai gave up

// This script was created with an AI assistant to debug an environmental issue.
// The goal is to load tags from an external text file, let the user select from a list,
// and add the selection as keywords to the selected files.
// However, multiple core functions of the DOpus script object model fail in my environment.

function OnInit(initData) {
    initData.name = "TagLoader";
    initData.version = "Final Bug Report";
    initData.copyright = "(c) 2025 Chet gpt & Gemini";
    initData.desc = "Loads a list of tags from an external text file and adds them as keywords.";
    initData.default_enable = true;
    initData.min_version = "13.0";

    var cmd = initData.AddCommand();
    cmd.name = "RunTagLoader";
    cmd.label = "Add Tags From File";
    cmd.method = "OnRunTagLoader";
    cmd.template = "files/m";
    cmd.icon = "tag";
}

function OnRunTagLoader(scriptCmdData) {
    var func = scriptCmdData.func;
    var DOpus = func.DOpus;

    // The path to the external text file containing one tag per line.
    var tagFilePath = "D:\\Teglist.txt";

    // --- TROUBLESHOOTING NOTE 1: File Reading ---
    // We are using DOpus.FSUtil because the standard ActiveXObject("Scripting.FileSystemObject")
    // failed to correctly handle Korean character encoding, resulting in garbled text.
    // However, the line below (`DOpus.FSUtil()`) has also failed in the past with an
    // "'undefined' is null or not an object" error, indicating the DOpus object is not fully available.
    var fsu = DOpus.FSUtil();
    var myTags = [];

    if (!fsu.Exists(tagFilePath)) {
        DOpus.Dlg.Alert("Tag file does not exist.\nPath: " + tagFilePath);
        return;
    }

    var tagVec = fsu.ReadAsVector(tagFilePath);
    for (var i = 0; i < tagVec.count; i++) {
        var line = new String(tagVec[i]);
        if (line.replace(/\s/g, '').length > 0) {
            myTags.push(line);
        }
    }

    if (myTags.length == 0) {
        DOpus.Dlg.Alert("The tag file is empty.");
        return;
    }
    
    // --- TROUBLESHOOTING NOTE 2: Dialog Creation ---
    // We are using GetMultiChoice because DOpus.Create.Dialog() also failed with an
    // "Object doesn't support this property or method" error. GetMultiChoice is the
    // simplest dialog available, but it also fails in this environment.
    var selectedIndices = func.Dlg.GetMultiChoice(
        "Tags loaded from file. Please select items to add as keywords.",
        "Select Tags",
        myTags,
        0
    );

    // --- TROUBLESHOOTING NOTE 3: Return Type Handling ---
    // The GetMultiChoice function returns different data types (object, number, boolean)
    // depending on user action (multi-select, single-select, cancel).
    // The following block is a workaround to prevent "Object doesn't support..." errors
    // when trying to access properties like ".count" on a number or boolean.
    var tagsToAdd = "";
    if (typeof selectedIndices == 'object' && selectedIndices.count > 0) {
        for (var i = 0; i < selectedIndices.count; i++) {
            tagsToAdd += myTags[selectedIndices[i]] + ",";
        }
    } else if (typeof selectedIndices == 'number') {
        tagsToAdd = myTags[selectedIndices] + ",";
    } else {
        return; // User likely cancelled.
    }

    tagsToAdd = new String(tagsToAdd).slice(0, -1);
    if (tagsToAdd.length == 0) return;

    // --- TROUBLESHOOTING NOTE 4: The Final Bug ---
    // This is the final point of failure. Even when the script successfully gathers
    // the tags, this command fails with a "Meta parsing error".
    // This ONLY happens for the "keywords" field. A similar command for "comment"
    // (e.g., SetAttr META "comment:test") works correctly on the same files.
    // Manually editing keywords via the GUI also works correctly.
    // The bug appears to be specific to the SetAttr command's handling of "keywords:+"
    var commandLine = 'SetAttr META "keywords:+' + tagsToAdd + '"';
    func.command.RunCommand(commandLine);
}

Right now I don't even know what's wrong with this code. Sorry and thank you!

The metadata pane is not open to scripting. You could use a standard script dialog or a FAYT script for this.

1 Like

AI cannot write code, and errors in AI-generated code are not bugs in Opus. They're because AI is useless at this kind of task.

If you want someone to write a script for you, create a thread with the details of what you want. If people have time and it's not too complicated, they will often write things for you.

OTOH, asking people to clean up a mess of random code produced by an AI is a waste of your time and theirs, as is filing bug reports because the code an AI generated doesn't work. Of course it doesn't work. AIs cannot write code.

1 Like

100% aligned with Leo.

So you can see the mess, here's the provided code commented with everything's wrong at first sight (all the // ERROR comments):

// This script was created with an AI assistant to debug an environmental issue.
// The goal is to load tags from an external text file, let the user select from a list,
// and add the selection as keywords to the selected files.
// However, multiple core functions of the DOpus script object model fail in my environment.

function OnInit(initData) {
    initData.name = "TagLoader";
    initData.version = "Final Bug Report";
    initData.copyright = "(c) 2025 Chet gpt & Gemini";
    initData.desc = "Loads a list of tags from an external text file and adds them as keywords.";
    initData.default_enable = true;
    initData.min_version = "13.0";

    var cmd = initData.AddCommand();
    cmd.name = "RunTagLoader";
    cmd.label = "Add Tags From File";
    cmd.method = "OnRunTagLoader";
    cmd.template = "files/m";       // ERROR : What's this for? It's never used in the code below
    cmd.icon = "tag";
}

function OnRunTagLoader(scriptCmdData) {
    var func = scriptCmdData.func;
    var DOpus = func.DOpus;     // ERROR : property DOpus does not exist on func object + will clash with the actual DOpus object

    // The path to the external text file containing one tag per line.
    var tagFilePath = "D:\\Teglist.txt";

    // --- TROUBLESHOOTING NOTE 1: File Reading ---
    // We are using DOpus.FSUtil because the standard ActiveXObject("Scripting.FileSystemObject")
    // failed to correctly handle Korean character encoding, resulting in garbled text.
    // However, the line below (`DOpus.FSUtil()`) has also failed in the past with an
    // "'undefined' is null or not an object" error, indicating the DOpus object is not fully available.
    var fsu = DOpus.FSUtil();       // ERROR : Could work if DOpus had not been redefined
    var myTags = [];

    if (!fsu.Exists(tagFilePath)) {
        DOpus.Dlg.Alert("Tag file does not exist.\nPath: " + tagFilePath);      // ERROR : No such method on DOpus.Dlg object
        return;
    }

    var tagVec = fsu.ReadAsVector(tagFilePath);     // ERROR : No such method on FSUtil object
    for (var i = 0; i < tagVec.count; i++) {
        var line = new String(tagVec[i]);
        if (line.replace(/\s/g, '').length > 0) {
            myTags.push(line);
        }
    }

    if (myTags.length == 0) {
        DOpus.Dlg.Alert("The tag file is empty.");     // ERROR : See above comment about that method
        return;
    }
    
    // --- TROUBLESHOOTING NOTE 2: Dialog Creation ---
    // We are using GetMultiChoice because DOpus.Create.Dialog() also failed with an
    // "Object doesn't support this property or method" error. GetMultiChoice is the
    // simplest dialog available, but it also fails in this environment.
    var selectedIndices = func.Dlg.GetMultiChoice(          // ERROR : No such method on Dialog object
        "Tags loaded from file. Please select items to add as keywords.",
        "Select Tags",
        myTags,
        0
    );

    // --- TROUBLESHOOTING NOTE 3: Return Type Handling ---
    // The GetMultiChoice function returns different data types (object, number, boolean)
    // depending on user action (multi-select, single-select, cancel).
    // The following block is a workaround to prevent "Object doesn't support..." errors
    // when trying to access properties like ".count" on a number or boolean.
    var tagsToAdd = "";
    if (typeof selectedIndices == 'object' && selectedIndices.count > 0) {
        for (var i = 0; i < selectedIndices.count; i++) {
            tagsToAdd += myTags[selectedIndices[i]] + ",";
        }
    } else if (typeof selectedIndices == 'number') {
        tagsToAdd = myTags[selectedIndices] + ",";
    } else {
        return; // User likely cancelled.
    }

    tagsToAdd = new String(tagsToAdd).slice(0, -1);
    if (tagsToAdd.length == 0) return;

    // --- TROUBLESHOOTING NOTE 4: The Final Bug ---
    // This is the final point of failure. Even when the script successfully gathers
    // the tags, this command fails with a "Meta parsing error".
    // This ONLY happens for the "keywords" field. A similar command for "comment"
    // (e.g., SetAttr META "comment:test") works correctly on the same files.
    // Manually editing keywords via the GUI also works correctly.
    // The bug appears to be specific to the SetAttr command's handling of "keywords:+"
    var commandLine = 'SetAttr META "keywords:+' + tagsToAdd + '"';     // ERROR : No sych syntax with 1) an array of tags (proper syntax is a comma separated string), 2) the + sign (no such syntax allowed to my knowledge - proper way : retrieve existing tags and build new list)
    func.command.RunCommand(commandLine);
}

As you can see, this can not be just fixed, there are way too many mistakes.

Explain your use case and what you want to achieve, and hope someone here will be eager to help (which, as Leo said, will probably be the case if you don't ask for something too complicated).

1 Like

There are a number of tagging tools in the Scripts area, and since they're written by humans they actually work.

1 Like

Thank you all for watching the strange code I made with Ai with interest. I asked Ai because I thought it was a waste of time on someone. But it was better to make a thread and ask people to do it. Thank you for the good opinion! I will organize it and upload it sometime. Thank you for the good advice, developers!