Action inserted in non-displayed macro

Today is the first time I’ve ever seen this behavior of the KM editor. I have a macro open in the right pane of the editor. I double click on an action in the Actions window in the left side of the editor. Nothing gets inserted. I try again several times. Nothing happens. Different actions, still nothing. A few minutes later I notice that all those actions were inserted into a different macro, not the one currently on display. It seems to have happened more than once today but it’s hard for me to find which macros the actions ended up in because it’s not the active macro.

I realize that about 50% of all user bug reports are wrong, but I’m willing to take the chance.

I have been using KM for years, and have never seen this behavior, nor even heard of it.
It is likely something that you are doing in the UI.

First troubleshooting step is to stop/start the KM Engine, and then quit/launch the KM Editor app.
Make sure the KM Editor is in EDIT mode. In the menu, you should see View > Stop Editing Macros

If you are still seeing this behavior, then it would be best to record a short video/animated GIF showing the behavior, and then post that.

The only way I could imagine this happening is if some sort of exception is happening in the editor so that it is not displaying the correct macro.

Since this is nothing I have ever heard of, and very weird behaviour, this is one of the rare times I would suggest first relaunching Keyboard Maestro and then if the behaviour continues, restarting, since the issue may be a system corruption or the like that is causing something that normally works to fail.

If it continues (or perhaps even if it doesn’t), you should look in the Editor.log file for any errors reports (Help ➤ Open Logs Folder). Or the Console, but it is nearly impossible to see anything in there these days because it is so full of noise.

I had never noticed the logs before. KM always has new surprises for me. First I opened Editor.log. I see from weeks past occurrences of 450 error lines per second, typically looking like this: “2018-03-11 03:36:05 Assertion Failed: us, file: /Users/peter/Keyboard Maestro/Project/Source/ActionEditors/AExecuteMacroEditor.mm:118, value: 0” (which is Peter N Lewis’ username, for his source code, not mine). There appear to be no relevant messages in this file during the timeframe I was having the problem.

I also checked the Engine.log file. It’s a very interesting file. I’ll check it out more often in the future. And it does contain roughly 450 error lines per second for a period of time today. It’s possible this may correspond to the times when I had to restart the engine due to some problems. A typical error line is “2018-03-15 19:58:08 Assertion Failed: newValue, file: /Users/peter/Keyboard Maestro/Project/Source/Defines/KMVariables.mm:345, value: 0”.

I’ve read lots of log files in my life so I’m eager to keep an eye on these going forward. I don’t really want to paste large portions of my log files here because I build things with servos and don’t want any of my trade secrets revealed on these forums (my macro names may give away too much). But I’d be happy to sanitize the files if there’s something you need to see. For now, you’ve given me great advice to help resolve this.

In fact, I may very well try to write a KM macro that reads the tails of these two files and pops up alerts when something new and unexpected is logged. I don’t think KM has direct support for growing text files so I’ll probably have to wing something using my bag of UNIX tricks. For example I may use KM’s trigger to detect new files in a folder as the means to get error messages passed to it. That could be very useful to a lot of KM users.

The AExecuteMacroEditor.mm:118 assertion is basically the Execute Macro action editor saying that it cannot find the action associated with it, which is the sort of thing that would go along with your case of the actions being inserted in the wrong place - basically the editor is there, but the macro action behind it is not, which indicates some level of confusion on the editor’s part.

The KMVariables.mm:345 is strange. It indicates it is trying to set a variable to a nil value, and I checked every possible way that code can be executed, and all of them either explicitly have a non-nil value, or actively force the parameter or be non-nil, or assert other previous failings. So other than failing to create trivial strings, which would mean your Mac was fairly badly messed up at that point, I don’t know how this one could happen.

So yes, step one would be Restart, and verify the issue survives that, but after that I don’t really know where to go, since those two failures do not give a lot of indication as to what the problem might be.

Your support is appreciated, but I haven’t had that problem since. More commonly, perhaps once or twice per week I get into the situation where the KME is “not responding” and I notice it has grabbed 4.5-6 GB of RAM. So I have to restart the engine regularly. I guess I should be checking the logs around those times, but until now I hadn’t known about the logs at all. It doesn’t bother me a whole lot, because I enjoy the product so much every day I don’t mind an occasional fault. But I could investigate this problem now that I know about the logs.

Sounds like some sort of memory leak, although it is hard to say much more than that. Most of the serious memory leaks in the past have been related to image searching, but I don’t know of any remaining leaks.

Both of these behaviors are highly unusual. I've been using KM for years and have never observed anything like that, nor have I seen other users complain about it. I also have several colleagues that are KM power users, and AFAIK they have see this type of behavior.

It is very strange that the KM Engine is using 4.5-6 GB of RAM. That makes me think you must have some KM Variables that are storing very large amounts of data, maybe even binary data. I suggest you review your KM Variables, and Named Clipboards, in the KM Editor Preferences, and delete everything that you don't need. If you need to store large amounts of data then do so in files, NOT KM Variables or Named Clipboards.

As a standard practice, I now use only KM Local or Instance Variables unless I absolutely need the Variable for other Macros or subsequent executions of the same macro.

Here is a JXA Script that will export KM Engine Log entires that are abnormal, meaning it excludes the entries for normal Macro execution.
If you want to see all of the last 200 entries, just comment out this line:
oDoc.text = logErrorsList.join("\n");

JXA Script to Export to BBEdit Last 200 KM Engine Logs

'use strict';
(function run() {

var ptyScriptName   = "Copy Last KM Engine Log Entries to BBEdit"
var ptyScriptVer    = "2.0"
var ptyScriptDate   = "2018-03-20"
var ptyScriptAuthor = "@JMichaelTX"
/*
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
RETURNS:  One of these, as text:
  • Actual Log Entry (String) for LAST Error Log
  • "[ERROR]" at start of results if a script error occurred.
  
KM VARIABALES REQUIRED:
  • NONE
  
KM VARIABLES SET:
  • NONE
  
REF:
  • Chris Stone (@ccstone), email, 2016-10-18, Shell Script to Read KM Log
  
TAGS:  @errors @KM @Macro @Log @JXA @ShellScript @ccstone
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/
var returnResults = "TBD"  // Set your results to this var

try {
  //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  
var app = Application.currentApplication()
app.includeStandardAdditions = true

//--- GET THE LAST 200 LOG ENTRIES ---

var cmdStr = "tail -n 200 ~/\"Library/Logs/Keyboard Maestro/Engine.log\""; // thanks to Chris Stone
var logList = app.doShellScript(cmdStr);

logList = logList.split(/[\r\n]/);  // split using EITHER RETURN or NEWLINE

//--- FILTER LIST TO ONLY THOSE WITH ACTUAL ERRORS ---

var logErrorsList = logList.filter(function (pArrayElem) {
      //--- EXCLUDE Logs with below text (normal Macro Execution) ---
       return ! (/Execute macro|Running application/i.test(pArrayElem));
      //return (/while executing|execution error/i.test(pArrayElem));
    });

//--- GET THE LAST ERROR LOG ENTERED ---
//returnResults = logErrorsList[logErrorsList.length-1]


returnResults = logList.join("\n");

var bbeApp = Application("BBEdit");
bbeApp.activate();
var oDoc = bbeApp.TextDocument().make()
//oDoc.text = logList.join("\n");

//--- Output Only Abnormal Log Entires ---
oDoc.text = logErrorsList.join("\n");

  //~~~~ END TRY ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

} catch (oError) {
  
  console.log(oError);
  
    returnResults = "[ERROR]\n\n"
      + "SCRIPT: " + ptyScriptName + "   Ver: " + ptyScriptVer + "\n"
      + "Error Number: " + oError.errorNumber + "\n"
      + oError.message
  
} // END catch
//~~~~ END TRY/CATCH BLOCK ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

return returnResults

})();

1 Like

I don’t believe I store any binary data, and I don’t think of 450 variables as “too many” since most of them are a single number, or a short list of numbers, or one line of text. I think I do have one variable that contains perhaps 500 lines of text, but that variable has been around for only a month and this problem has been around for years, even on previous hardware before I got his iMac. Is there a way, perhaps using a KM macro, to show me the names of my variables that use the most space? Using the Preferences: Variables pane of KM is a very inefficient way to find out which of my variables are “big”.

Since KM introduced Local variables recently, I have been starting to use them. One problem I face with using them is that they are only visible when the macro is running which makes debugging much harder, since I can’t run portions of the macro and still see the value of the variable. Once I’ve debugged my macros I’m usually too lazy to backtrack and convert my variables to local variables. If only I didn’t have to edit every single occurrence of a variable to make it a local variable!

You showed me a JXA script. I had to google what that was. When I goggled it said JXA can be run in the MacOS Script Editor application. I tried that, but it gave me a compile error on the first line “Syntax Error: A unknown token can’t go here.” Obviously I’m not in your league, but I tried to understand.

P.S. I think you meant to say that your colleagues do NOT experience this behavior.

Maybe this will help.
Run this script in the Script Editor (or Script Debugger if you have it), and then paste the results into spreadsheet like Excel.

If you want, you can use this list to get a list of Variables that you want to delete. I have another script that will use that list to delete them.

AppleScript to Sort All KM Variables by Size Descending

Requires:
BridgePlus Script Library v1.3.2
Download to ~/Library/Script Libraries
This is a great AppleScript Script LIbrary by the well-known AppleScript guru @ShaneStanley.

Example Output (in Excel)

image

The size is the number of characters in the Variable.

property ptyScriptName : "Get All KM Variables & Sort by Size"
property ptyScriptVer : "1.1"
property ptyScriptDate : "2018-03-21"
property ptyScriptAuthor : "JMichaelTX"
use AppleScript version "2.5" -- El Capitan (10.11) or later
use framework "Foundation"
use framework "AppKit"
use scripting additions

#  This script has been tested ONLY in macOS 10.12.6

(*
REQUiRES:
  1. BPLib Script Library
      [BridgePlus Script Library v1.3.2]
      (https://www.macosxautomation.com/applescript/apps/BridgePlus.html)
      Download to ~/Library/Script Libraries
*)

use BPLib : script "BridgePlus" -- required to sort lists
load framework

tell application "Keyboard Maestro Engine"
  tell every variable
    set nameList to name
    set valueList to value
  end tell
end tell

set numVar to count of nameList
set kmVarList to {}

repeat with i from 1 to numVar
  set len to length of (item i of valueList)
  set end of kmVarList to {item i of nameList, len}
end repeat

set kmVarList to BPLib's sublistsIn:kmVarList sortedByIndexes:{2, 1} ascending:{false, true} sortTypes:{}

set AppleScript's text item delimiters to tab
repeat with oItem in kmVarList
  set contents of oItem to (oItem as text)
end repeat

set AppleScript's text item delimiters to linefeed

set kmListStr to kmVarList as text
set the clipboard to kmListStr

set currentApp to path to frontmost application as text

tell application currentApp
  set msgStr to "A Tab-Delimited list of all of your KM Variable is on the Clipboard.  Paste into Excel to view."
  set msgTitleStr to ptyScriptName
  display dialog msgStr with title msgTitleStr ¬
    with icon note
  --etc
end tell


For that to work I would have to install the BridgePlus Script Library. I will need to consider who wrote it, and what it does before I install it. That would be a lot of work, so I just decided to solve the problem using KM itself. Hope you don't mind. :slight_smile:

I presume I get "extra credit" for this cool solution. It illustrates a couple of neat features of KM.

KM is usually pretty fast, although it's a bit odd that this particular routine feels slow. My 450 variables took 15 seconds to report, which means KM could process only 30 variables per second. To me that feels very slow.

However I did discover I do have a variable with binary contents. It's a variable I use to communicate with my Arduino Esplora. I use it, so I can't delete it. But it can't be the cause of the KME memory issues since I've only had that working for a few weeks.

Anyway thanks for your help, even though I found a KM solution to this problem.

My script is extremely fast -- less than 1 sec for 500 variables.