Teaser

Let’s say you’re on Mac and trying to copy a folder from an external drive into your mac. But when you copy, you encounter this error:

The operation can't be completed because one or more required items can't be found. (Error code -43)

Weird. What’s Error code -43 anyway?

So you pop open the terminal and try to copy the files by hand.

16:14:32 0  :/Volumes/UNENCRYPTED/Music/Lo-fi/Lofi Girl$ cp -r 4\ A.M\ Study\ Session/ ~/
cp: 4 A.M Study Session//02 Tom Doolie ft. lōland - Parallel.ogg: No such file or directory
16:14:43 1  :/Volumes/UNENCRYPTED/Music/Lo-fi/Lofi Girl$

Weird.

16:15:19 1  :/Volumes/UNENCRYPTED/Music/Lo-fi/Lofi Girl$ ls -l 4\ A.M\ Study\ Session/
total 273408
-rwx------  1 elfakyn  staff  7467827 10 Dec 22:16 01 Purrple Cat - Snooze Button.ogg
-rwx------  1 elfakyn  staff  5040669 10 Dec 22:16 02 Tom Doolie ft. lōland - Parallel.ogg
-rwx------  1 elfakyn  staff  5746920 10 Dec 22:16 03 jhove - Counting Sheep.ogg
-rwx------  1 elfakyn  staff  4119538 10 Dec 22:16 04 Dontcry ft. Nokiaa - Bliss.ogg
-rwx------  1 elfakyn  staff  6855095 10 Dec 22:16 05 amies - Above the Clouds.ogg
-rwx------  1 elfakyn  staff  5064945 10 Dec 22:16 06 Tenno - Sayonara.ogg
-rwx------  1 elfakyn  staff  5068349 10 Dec 22:16 07 Kayou - Im Fine.ogg
-rwx------  1 elfakyn  staff  5421985 10 Dec 22:16 08 Thaehan - Secret Garden.ogg
-rwx------  1 elfakyn  staff  6012518 10 Dec 22:16 09 No Spirit - Carry Me.ogg
-rwx------  1 elfakyn  staff  5364721 10 Dec 22:16 10 lōland ft. Nokiaa, Tom Doolie - Alaska.ogg
-rwx------  1 elfakyn  staff  4733125 10 Dec 22:16 11 l'Outlander ft. Kanisan - Night Walk.ogg
-rwx------  1 elfakyn  staff  4712329 10 Dec 22:16 12 Miramare ft. Clément Matrat - Drowsy Town.ogg
-rwx------  1 elfakyn  staff  4450606 10 Dec 22:16 13 lilac - Nemui.ogg
-rwx------  1 elfakyn  staff  3712970 10 Dec 22:16 14 Yasumu - Sunsets.ogg
-rwx------  1 elfakyn  staff  5901133 10 Dec 22:16 15 dryhope - Voyager.ogg
-rwx------  1 elfakyn  staff  5334232 10 Dec 22:16 16 sleepermane ft. Sling Dilly - Shimmer.ogg
-rwx------  1 elfakyn  staff  5407399 10 Dec 22:16 17 Ky akasha - Night Drive.ogg
-rwx------  1 elfakyn  staff  3800806 10 Dec 22:16 18 Kanisan ft. Hoogway - Drowning.ogg
-rwx------  1 elfakyn  staff  5351730 10 Dec 22:16 19 Mondo Loops ft. Yasumu - Shimmering Nights.ogg
-rwx------  1 elfakyn  staff  5366079 10 Dec 22:16 20 cxlt. - Everything Went Quiet.ogg
-rwx------  1 elfakyn  staff  4862023 10 Dec 22:16 21 Chiccotes Beats ft. Pueblo Vista - Lullaby.ogg
-rwx------  1 elfakyn  staff  5101117 10 Dec 22:16 22 amies ft. cxlt. - Imaginary.ogg
-rwx------  1 elfakyn  staff  8930736 10 Dec 22:16 23 Arbour - Patience.ogg
-rwx------  1 elfakyn  staff  4351244 10 Dec 22:16 24 Sebastian Kamae - Midsummer.ogg
-rwx------  1 elfakyn  staff  4001637 10 Dec 22:16 25 Living Room - Rainbowsend.ogg

The file is there. Weird.

So the file isn’t there?

16:15:45 0  :/Volumes/UNENCRYPTED/Music/Lo-fi/Lofi Girl$ ls 4\ A.M\ Study\ Session/02\ Tom\ Doolie\ ft.\ lōland\ -\ Parallel.ogg
ls: 4 A.M Study Session/02 Tom Doolie ft. lōland - Parallel.ogg: No such file or directory
16:16:22 1  :/Volumes/UNENCRYPTED/Music/Lo-fi/Lofi Girl$

What the fuck is going on?

Unicode decomposition of the file name, showing "Combinind Macron"

Ah.

What’s really going on

The filenames that you’re copying aren’t properly Unicode normalized as required by the Mac HFS filesystem.

Unicode allows some sequences of characters to be represented by multiple, equivalent forms. For example, the character "" can be represented as the single Unicode character u+00E9 (latin small letter e with acute), or as the two Unicode characters u+0065 and u+0301 (the letter “e” plus a combining acute symbol).

To reduce complexity in the B-tree key comparison routines (which have to compare Unicode strings), HFS Plus defines that Unicode strings will be stored in fully decomposed form, with composing characters stored in canonical order. The other equivalent forms are illegal in HFS Plus strings. An implementation must convert these equivalent forms to the fully decomposed form before storing the string on disk.

MacOS makes a catastrophic assumption: that all files (even those stored in a different filesystem such as exFAT) have Unicode-normalized file names. This leads to the above errors.

How to fix

To fix them, you need to perform NFC normalization on the file names. You need to do this on a different operating system. I used Linux under WSL. Here’s a (really inefficient) shell command to fix all files in the current directory, recursively:

find . -depth -print0 | while IFS= read -r -d '' file; do
    normalized=$(python3 -c "import unicodedata, sys; print(unicodedata.normalize('NFC', sys.argv[1]))" "$file")
    if [ "$file" != "$normalized" ]; then
        mv "$file" "$normalized"
    fi
done

That’s it!