Cleaning Up Variables at the end of sub-macros

Oh, one more thing. I totally want to use this macro. I just have to figure out how, since I have stuff running all the time. I might just use it on demand - not sure yet. There’s got to be a solution I haven’t thought of yet. This is just too good to pass up.

Thanks for the heads-up.

I think this issue is solved using the new option for Set Variable: "Process Nothing":

I was thinking of doing exactly that. Thanks for the confirmation.


Hey Folks,

You realize you can do something like this?

tell application "Keyboard Maestro Engine"
   set value of variables whose name ends with "_tmp" to "%Delete%"
end tell


_[EDIT: Changed typo “.tmp” to “tmp” – thanks Dan!]


A good “find”. Thanks.

Chris -

I wouldn’t have thought a variable name could include a period. The Wiki says

Variable names must start with a letter, and then can contain letters, numbers, spaces, or underscores.

Plus, I wouldn’t feel comfortable using a period even if it does happen to work now, because of potential conflicts with things like .Left, etc.

What’s your thoughts.

It’s certainly not my style.

I tend to use camelCase just because I’m in the habit of doing so in AppleScript and JXA/JS.

However, I do sometimes use underscores, and I could see the utility of using “_tmp”, as in “macroName_tmp

I agree. If I were going to try to delete variables like this, I would use underscores.

But again, the problem with something like this is it deletes all variables that end with “_tmp” (or whatever), not just those used by a specific macro.

Now that I’m using DND__ at the start of the variable names for variables I want to persist, and I’m still prefixing the variable names with something to tie them to the macro (like “minst” that I’m working on right now), I can pretty safely do this:

tell application "Keyboard Maestro Engine"
    set value of variables whose name starts with "minst" to "%Delete%"
end tell

(I just figured this out. I’m slow.)

So, I’ve got that going for me. :slight_smile:

Hey Dan,

You’re right. I meant to type an underscore.


1 Like

You can use starts with, contains, or ends with, so you have a reasonable amount of flexibility.

1 Like

For anyone who cares, here’s an example of how to do this in JXA:

var kme = Application("Keyboard Maestro Engine");
    .whose({ name: { _beginsWith: "minst" } }).name()
    .forEach(function(varName) {
        kme.setvariable(varName, { to: "%Delete%" });

Notice the _beginsWith specifier. You can see a whole bunch more of these specifiers (or whatever the correct term for them is), for example _contains and _endsWith, at OS X 10.10 Release Notes and search for “Filtering Arrays”, which is near the top.

1 Like

Is there a means to detect file attachment failures to mail messages using Chrome Gmail?


I've adopted the practice of deleting no longer needed variables at the end of my macros.

However, if the macro encounter errors, I may wish to avoid the deletion based upon some detectable condition.
Group.kmactions (1.5 KB)

Hey @KM_Panther,

You said it right there detectable condition.

You might be able to see it with JavaScript.

You might be able to see it by getting the source of the page and searching for “Attachment Failed”.

You can get the page text (NOT the source) with AppleScript and parse it.

tell application "Safari"
   tell front document
      set safariPageText to its text
   end tell
end tell

** You can get the page source with “its source” instead of “its text”.

You can parse for “Attachment Failed” or the attachment file name(s). This works to find the file names – I just tried it. I can’t force an attachment to fail though, so I can’t test for that.

The trick here would be the timing of the scan(s) after attaching the files.

The advantage of scanning for the attachment file name(s) is that you can keep scanning until they are found (with a timeout) and continue only after they are seen.


Not deleting the variables in the case where the macro fails is a good idea.

You can probably detect the “Attachment failed” text by looking at the text of the web page. Something like Execute JavaScript in Chrome document.documentElement.innerHTML and search that.

Alternatively you could use Find Image on Screen, but text will likely be faster and more reliable.

Hey @KM_Panther,

Whups, I forgot you were using Chrome.

This should work:

tell application "Google Chrome"
   tell active tab of front window
      set visibleText to execute javascript "document.documentElement.innerText"
   end tell
end tell

And of course you can use the bare JavaScript in either an Execute a JavaScript in Google Chrome action or an Execute a JavaScript in Safari Keyboard Maestro action.


Chris & Peter,

As an aside, In order to get the image of the attachment failure for posting, I forced the failure by turning off my WiFi radio while the file was being attached. You may not have been able to do that for your testing.

Also, I used the attachment failure as an example, but I suppose there could be other reasons for the email failure (e.g. incorrect address syntax). Is there any way to capture a code or something that indicates the message was successfully sent like the message below that appears?

I have been learning AppleScript, but not JavaScript. I'll try your suggestions.

Thanks for your continued assistance!


Chris & Peter,

It works great!

Most, if not all, Actions that encounter an error will automatically cause the Macro to abort, UNLESS you have unchecked one of these:

  • Timeout aborts macro
  • Failure aborts macro

Of course, if the KM Action has no way of knowing whether or not some external software (app, macOS, etc) has a failure, then this will not work.

For example, KM Action "Execute an AppleScript " does NOT abort even if the script returns an error.
So, in all my AppleScript and JXA scripts, I return "[ERROR]\n" and the error message. I then have a KM Group (set of actions) that check for the error and handle accordingly:

I just uploaded this macro (which is really just a Group Action) that I use:

MACRO: KM Group Action to Handle Script Error