Wrong Folder Returned by ‘path to’ Command in System Events Tell Blocks

The Standard Additions scripting addition defines the path to command; you tell it which folder you want, it returns an alias pointing to that folder.

So, for example, you can say:

set p1 to path to application support

And it will return an alias to the “Application Support” folder in your top-level Library folder. Aliases use HFS-style paths, so the result (p1 in this case) will look something like this:

Tycho HD:Library:Application Support:

There are a couple of dozen special folder names you can pass to path to, including documents folder, favorites folder, desktop, and so forth. Consult the Standard Additions scripting dictionary for the full list.

Because of the layered system folder layout on Mac OS X, there are more than one instance of some of these folders. For example, with the “Application Support” folder, there’s one in the top-level “Library” folder, and there’s another one inside the “Library” folder in each user’s home folder.

These different layers are called file-system domains in Mac OS X’s parlance.1 You can pass the path to command a from parameter, which allows you to specify which domain you want. As evidenced above, if you omit the from parameter, it defaults to the Local domain (i.e. the top-level “Library” folder shared by all users).

To get the current user’s “Application Support” folder, ask for the User domain:

set p1 to path to application support from user domain

This returns something like:

Tycho HD:Users:gruber:Library:Application Support:

So, given all that, take a guess what this returns:

tell application "System Events"
    set p2 to path to application support from user domain
end tell

The reasonable guess, of course, is that it would return the same thing. Alas, no. Instead, in the above snippet, p2 is set to:

Tycho HD:Library:Application Support:

I.e. by placing the path to command within a tell application "System Events" block, it no longer honors the from user domain parameter, and instead always returns the folder from the Local domain.

This is particularly insidious because inside a tell application "System Events" block is exactly where you’re likely to want to get the path to a folder, because you can’t do much with an alias to a folder except within such a block. AppleScript, by itself, doesn’t let you do anything with a folder.

For example, let’s say you want to get a list of every item within the user’s “Application Support” folder. You can’t just say this:

set p to path to application support from user domain
set my_list to every item of p

because you’ll get an error on the every item of part. You need to ask an application that knows how to do something with a folder. The Finder can do this, but the recommended way to script this is to use System Events instead. But you can’t just say this:

tell application "System Events"
    set p to path to application support from user domain
    set my_list to every item of p
end tell

because once you move the path to command into the System Events tell block, you get the wrong answer. Instead, you have to remember this, and write it like this, with the path to statement outside the tell block:

set p to path to application support from user domain
tell application "System Events"
    set my_list to every item of p
end tell

The Finder, however, does not suffer from the same bug as System Events.2 This works as expected:

tell application "Finder"
    set p to path to application support from user domain
    set my_list to every item of p
end tell

The reason to prefer System Events over Finder for this sort of thing is that, ostensibly, Finder is technically “optional” — users of third-party file managers like Path Finder might not be using the Finder. System Events, however, is always available.

This sort of bug is precisely why so many people despise AppleScript. Not only does it make no sense, but something like this can be maddeningly difficult to track down. Imagine if you start with the path to statement outside the System Events tell block, and everything is working as you expect. Then, while cleaning up the code, you move the path to statement into the tell block, to keep it next to the other lines of code that pertain to the folder you’re getting the path to.

Now your script is broken — but you may not notice immediately, because it doesn’t break with a compilation or runtime error. Instead, just by moving the path to statement inside the System Events tell block, it silently starts returning a different (and wrong) “Application Support” folder.

For those of you keeping score at home: Radar 4255244.


  1. Cf. “The One and Only Mac OS X Extensions Folder” for more details about Mac OS X’s file-system domains.

  2. I have to assume this is a bug in System Events. If this isn’t a bug, but instead expected behavior, I’d love the explanation. Also note that this behavior is the same on 10.3.9 and 10.4.2.