Older Action Works, but Newly Created Copy Fails with JXA TypeError

I am encountering a confusing issue while working with KBM. I have a single macro with two separate actions: Action 1 & Action 2. Each action is executing the same JavaScript file for Automation (JXA). The script simply logs "hello" to the OmniFocus console. However, one action works as expected, while the other generates a TypeError.

Any help in understanding what the heck is going on would be greatly appreciated!

Here are the details:

SETUP
Action 1:

  • This action was copied from another macro and works without issues.
  • It successfully logs "hello" in the OmniFocus console.

Action 2:

  • This action was created fresh within the current macro and points to the exact same script file.
  • This action fails with the following error (details below).

SCRIPT USED BY BOTH ACTIONS

(() => {
    "use strict";
    // ------------------- OMNIJS CODE -------------------

    const OmniJS = () => {
        console.log("hello");
    };

    // -------------------- JXA CODE ---------------------

    const main = () => {
        return evalOmniJSWithArgs(
            "OmniFocus",
            OmniJS,
            ""
        );
    };

    // --------------------- GENERIC ---------------------

    // evalOmniJSWithArgs :: Function ->
    // [...OptionalArgs] -> a
    const evalOmniJSWithArgs = (appName, f, ...args) => {
        return Application(appName).evaluateJavascript(
            `(${f})(${args.map(JSON.stringify)})`
        );
    };

    return main();
})();

ERROR LOG GENERATED BY ACTION 2

2025-01-22 15:32:09 Execute a JavaScript For Automation failed with script error: 
Error: TypeError: { 
 } 
 is not a function. (In '{ 
 } 
(() => {
    "use strict";

    // ------------------- OMNIJS CODE -------------------

    const OmniJS = () => {
        console.log("hello");
    };

    // -------------------- JXA CODE ---------------------

    const main = () => {
        return evalOmniJSWithArgs(
            "OmniFocus",
            OmniJS,
            ""
        );
    };

    // --------------------- GENERIC ---------------------

    // evalOmniJSWithArgs :: Function ->
    // [...OptionalArgs] -> a
    const evalOmniJSWithArgs = (appName, f, ...args) => {
        return Application(appName).evaluateJavascript(
            `(${f})(${args.map(JSON.stringify)})`
        );
    };

    return main();
})', '{ 
 } 
' is an instance of Object) (-2700)

Are they both set to use the same syntax, via the drop-down menu to the left of the script box? I'm not a JXA person at all, but that would be my first guess—just for something simple to look at until the experts get here :).

-rob.

1 Like

If the actions behave differently, they are configured differently.

As @griffman notes, it is likely the configuration of the syntax as described at Execute a JavaScript For Automation.

As a hack way to figure this out, you could copy each action as XML and look for the differences.

2 Likes

Copied from
Created fresh

Keyboard Maestro V11 defaults to Modern Syntax (drop-down menu to left of code text field in Execute JXA error), and that will be the setting in your created afresh version.

I wrote the code which you have copied before KM11, and would write it differently now.

You will find that the action which you have copied will have Modern Syntax unchecked.


In Modern Syntax, as you will find when you read the documentation, the code requires a top-level return expression.

To fix your "afresh" action, either:

  1. precede the whole IIFE with return , or
  2. disable the "Modern Syntax" setting.

Oh wow!! I didn't even know that little down arrow was an actual drop down menu!!! Thank you~