To set a Finder tag programmatically

To set a Finder label, I can use

set thePath to POSIX file "/Users/john/Desktop/xyz.txt" as alias
tell application "Finder" to set label index of thePath to 1

But how to set a tag? On macOS 15.3.2, the following example throws an error:

set thePath to POSIX file "/Users/john/Desktop/xyz.txt" as alias
tell application "Finder" to set the tags of thePath to {"Important"}

ChatGPT suggests to install the tag command-line utility, but I would prefer to solve this task without third-party tools.

Did you google this site??

john202307. I’ve included below a summary of Shane’s handlers (plus one of my own) that will manipulate a file’s tags. These handlers will 1) get existing tags; 2) delete existing tags and set new tags; 3) add new tags to existing tags; 4) delete existing tags; and 5) delete one or more tags from the existing tags. I don’t know of any other approach (except perhaps GUI scripting and the shell utility you mention) that will do what you want.

--revised 2025.04.08

use framework "Foundation"
use scripting additions

set theFile to POSIX path of (choose file)

--get a list of existing tags
set theTags to getTags(theFile)

--delete existing tags and set new tags
set theTags to {"Tag One", "Tag Two"}
setTags(theFile, theTags)

--add new tags to existing tags
set theTags to {"Tag Three", "Tag Four"}
addTags(theFile, theTags)

--delete existing tags
setTags(theFile, {})

--delete specified tags
set tagsToDelete to {"Tag One", "Tag Two"}
set theResult to deleteSpecifiedTags(theFile, tagsToDelete) --false if all tagsToDelete not found

on getTags(theFile)
	set theFile to current application's |NSURL|'s fileURLWithPath:theFile
	set {theResult, theTags} to theFile's getResourceValue:(reference) forKey:(current application's NSURLTagNamesKey) |error|:(missing value)
	if theTags is missing value then return {}
	return theTags as list
end getTags

on setTags(theFile, theTags)
	set theFile to current application's |NSURL|'s fileURLWithPath:theFile
	theFile's setResourceValue:theTags forKey:(current application's NSURLTagNamesKey) |error|:(missing value)
end setTags

on addTags(theFile, theTags)
	set theFile to current application's |NSURL|'s fileURLWithPath:theFile
	set {theResult, existingTags} to theFile's getResourceValue:(reference) forKey:(current application's NSURLTagNamesKey) |error|:(missing value) --get existing tags
	if existingTags is not missing value then --add new tags to existing tags
		set theTags to existingTags's arrayByAddingObjectsFromArray:theTags
		set theTags to (current application's NSOrderedSet's orderedSetWithArray:theTags)'s allObjects() --delete any duplicates
	end if
	theFile's setResourceValue:theTags forKey:(current application's NSURLTagNamesKey) |error|:(missing value)
end addTags

on deleteSpecifiedTags(theFile, tagsToDelete)
	set theFile to current application's |NSURL|'s fileURLWithPath:theFile
	set {theResult, existingTags} to theFile's getResourceValue:(reference) forKey:(current application's NSURLTagNamesKey) |error|:(missing value) --get existing tags
	if existingTags is (missing value) then return false
	set theTags to existingTags's mutableCopy()
	theTags's removeObjectsInArray:tagsToDelete
	if theTags's isEqualToArray:existingTags then return false --all tagsToDelete not found
	theFile's setResourceValue:theTags forKey:(current application's NSURLTagNamesKey) |error|:(missing value)
	return true
end deleteSpecifiedTags
1 Like

I’ve never used tags on my computer and thought I’d write a script to learn a little about their operation. This script prompts the user to enter tags for a file selected in a Finder window. The tag names are capitalized by the script and are then set for the selected file.

--revised 2025.04.10

use framework "Foundation"
use scripting additions

--the separator that will be used to parse user input
set tagsSeparator to " "

--get file selected in Finder window
tell application "Finder" to set theFile to (selection as alias list)
if theFile is {} then display dialog "A file must be selected in a Finder window" buttons {"OK"} cancel button 1 default button 1
set theFile to current application's |NSURL|'s fileURLWithPath:(POSIX path of (item 1 of theFile))

--get existing tags of selected file
set {theResult, existingTags} to theFile's getResourceValue:(reference) forKey:(current application's NSURLTagNamesKey) |error|:(missing value)
if existingTags is (missing value) then
	set existingTags to "" --there are no tags in the selected file
else
	set existingTags to (existingTags's componentsJoinedByString:tagsSeparator) as text
end if

--prompt user for desired tags
set newTags to text returned of (display dialog "Enter tags for the selected file:" default answer existingTags)

--capitalize and delete duplicate tags
set newTags to (current application's NSString's stringWithString:newTags)
set newTags to (newTags's componentsSeparatedByString:tagsSeparator)'s valueForKey:"capitalizedString" --capitalize
set newTags to (current application's NSOrderedSet's orderedSetWithArray:newTags)'s allObjects() --delete duplicates

--set tags of selected file
theFile's setResourceValue:newTags forKey:(current application's NSURLTagNamesKey) |error|:(missing value)
1 Like