macOS Catalina: Fixing Emacs After an Upgrade

Since the upgrade to macOS Catalina, I’ve had two serious annoyances with Emacs. Here’s a little insight into how I fixed them.

Issue 1: I Couldn’t Access Certain Folders

After the upgrade, Emacs was unable to access special folders, like the Documents folder. This is a ramification of the User Data Protection enhancements that were made in Catalina.

Here’s the gist of why this exists: In a previous version, macOS started displaying user prompts (similar to iOS) to grant application permission for accessing things like contacts, photos, location, etc. These prompts were displayed when using special APIs designated for those purposes.

Alas, there was an easy way to bypass these prompts. Rather than using APIs to, say, access your contacts, you could just read the contact database via the filesystem. Catalina now enforces these permissions at the filesystem APIs, as well. This means that, because it doesn’t even ask for permission, Emacs is simply forbidden from accessing certain files.

Apple did provide an escape hatch: Full Disk Access. You, the user, can provide this privilege to an application, and it is allowed to access all files that your user would otherwise be able to access. It’s pretty easy: Go to the Security section of System Preferences, find Full Disk Access in the list, and then add Emacs:

But…this solution didn’t work. After doing this, I still couldn’t access my documents folder. Solving this is directly related to the second issue that’s been nagging me since the upgrade to Catalina.

Issue 2: Spotlight Can’t Bring Emacs to the Front

I commonly switch between applications on macOS by pressing cmd-space to bring up Spotlight, then the first few letters of the application name, and finally return. It’s often quicker than finding the icon via cmd-tab. Unfortunately, this method stopped working, too.

As it turns out, the binary embedded in Emacs.app is…actually not a binary. Instead, it’s a Ruby script. From the script:


#
# This launcher code is from emacsformacosx.com and is not part of Emacs
# proper. It exists so that there can be a single download that contains
# binaries for all supported Mac OS X versions.
#
# Why not just use a fat binary? Because fat binaries can only hold 1 of
# each architecture and Emacs has multiple x86_64 architectures binaries.
#
# Why are there multiple x86_64 binaries? Because the Emacs source does OS
# feature detection at compile time instead of at run-time. So if you build
# Emacs on 10.9 then it will contain hard-coded calls to 10.9 APIs and will
# not run on 10.6. If you compile it on 10.6, then it will also run on 10.9,
# but it won't take advantage of any of the features in 10.9.
#

Although this never caused problems on prior versions of macOS, here, it is responsible for both of these issues:

  • Full disk access does not apply to Emacs because the permissions were not granted to /usr/bin/ruby.
  • Emacs can’t be launched again because it is already running, but the running binary doesn’t actually match the Ruby script. Spotlight gives up.

The Solution

On Catalina, the Ruby script will always choose to launch the bundled binary Emacs-x86_64-10_14. So, if you simply move it in place of the Emacs launcher script, everything starts working as normal. At the Terminal, just run these commands:

% cd /Applications/Emacs.app/Contents/MacOS
% mv Emacs Emacs-launcher
% mv Emacs-x86_64-10_14 Emacs
% cd /Applications/Emacs.app/Contents/
% rm -rf _CodeSignature

And, with that, Emacs should correctly receive its Full Disk Access permission, and Spotlight will correctly bring it to front (n.b., it’s still required to add Emacs to the Full Disk Access section of the security system preferences).

Note that, because we have been performing surgery on the Emacs app, its code signature is no longer valid. The last command above removes the code signature from the Emacs binary. On my machines, I had no issues. If you can’t launch Emacs after running these commands, try following the steps in this document from Apple.

Conclusion

One final caveat: This works for me using homebrew-cask-installed Emacs version 26.3. In future versions of Emacs, it’s possible that the correct binary might be something other than Emacs-x86_64-10_14.

If you’ve been plagued by these problems, I hope this post helped.

Conversation
  • Igorsky says:

    Thank you so much! Saved a lot of my time

  • Peter Borocz says:

    Thanks Chris, This also solved an issue for those of us using Alfred, in particular the inability to bring window focus to emacs from the Alfred prompt. I suspected it was the ruby wrapper but wasn’t aware that simply pointing “Emacs” directly to the executable would work. FWIW, same wrapping is used for those of us installing from https://emacsformacosx.com/ (not only from brew)

  • Andrewcba says:

    Awesome, this worked for me.

  • olivier faugeras says:

    Thanks, it worked for me also.

  • HB says:

    Thank you! You save my day!

  • Vince says:

    Thanks so much for sharing this. Its the little things that make a workflow sometimes and this is one of those little/big things

  • D.N. says:

    Outstanding information. Thank you! (With MacOS, I always wait for the .4 sub-version before upgrading to the next major version, and it still burns me by breaking something important.)

  • D.N. says:

    This resolves a third major annoyance: with Catalina, ‘open’ command will not work correctly with Emacs.

    Use case: It is convenient to use ‘open’ in the Terminal to load files into a selected Emacs frame/buffer. That is, I have a shell function that invokes “open -a /Applications/Emacs.app “.

    The *correct* behavior is the following: (a) if needed, start an Emacs process and create a frame; and (b) open the file in a buffer. Subsequent ‘opens’ will instantiate a new buffer in the last active frame.

    With Catalina, the behavior broke: The first ‘open’ worked. The second, did nothing. One could add add -n to ‘open’, but it would creates a separate Emacs instantiation, not a new frame. Annoying!

  • Ingo Thies says:

    Thank you so much! It works like a charm for me.

  • RH says:

    Dude! Thank you so much :)

  • Jerry M. says:

    Thank you for posting this solution! Like others have said, it works and saved me the time (and suffering) from figuring it out myself.

  • Mickey Muldoon says:

    Thank you greatly. This should really be submitted as a bug fix to whomever maintains the homebrew repository.

  • Xavier Zhou says:

    Great thanks, you save me a whole day!
    I’m mapping a global shortcut key( `open -a emacs`) to bring the emacs to the foreground but found on Catalina it was not working anymore.
    You explained the exact reason and the solution with renaming the binary did work,
    just after that, I have to use `alias emacs=/Applications/Emacs.app/Contents/MacOS/Emacs` otherwise it complains some dependencies issues.

  • Pino Rosolini says:

    Great! Thank you so very much!

  • Rodrig says:

    THANKYOU. In my case I use Alfred instead of spotlight. Alfred was always able to find emacs since it looks for apps more in a ‘file finder’ way. But as it was launched without being able to access any files on Documents, Downloads etc… only ~/ and some root dirs. Swapping executables was the solution. Can’t thank you enough. I was going mad!

  • Patrick Brinich-Langlois says:

    The second tip literally saved my life. Thanks!

    • Patrick Brinich-Langlois says:

      This seems no longer to work (with Emacs 27.1 on macOS 10.15.6). I ran `brew cask install emacs`, then ran these commands:

      % cd /Applications/Emacs.app/Contents/MacOS
      % mv Emacs Emacs-launcher
      % mv Emacs-x86_64-10_14 Emacs
      % cd /Applications/Emacs.app/Contents/
      % rm -rf _CodeSignature

      Emacs won’t launch when I click on it, and when I run it from the command line, I get this error:

      ➜ emacs
      desired fingerprint: 1513df07bd6374caad1e71fd3321d0b02c6a2ac4ef976a9c7c310ed7f101603e
      found fingerprint: d98de63f776b864bf82895da82cc6c25b802bedfd8798d0783f99fdac1263ecf
      emacs: could not load dump file “/Applications/Emacs.app/Contents/MacOS/Emacs.pdmp”: not built for this Emacs executable

      • Chris Farber Chris Farber says:

        Hi Patrick,

        I think this must have something to do with Emacs’s new portable dumping. My first thought was that the name of the binary may in some way influence the fingerprint that’s computed.

        I tried creating a symlink from `Emacs` to `Emacs-x86_64-10_14`, and that does work.

        Try this instead of the third command:

        `ln -s Emacs-x86_64-10_14 Emacs`

        • Patrick Brinich-Langlois says:

          Cool, that works!

          The first time I tried this I got an “App is damaged and can’t be opened. You should move it to the Trash” error. Then I followed the same steps, except I opened Emacs once after running `brew cask install emacs`, and it worked. Thanks!

      • Angad Gill says:

        I faced the same error, so I moved renamed the corresponding .pdmp files as well

        Do this:
        mv Emacs.pdmp Emacs-launcher.pdmp
        mv Emacs-x86_64-10_14.pdmp Emacs.pdmp

        It should work after this

  • Stephen Moye says:

    I followed the directions — twice. Both times, Control-click->Open (after verifying), the Mac OS tells me that the application is damaged and should be moved to the trash. (Mac OS 10.15.5). What is wrong?

    Thanks.

    • Chris Farber Chris Farber says:

      I’m not sure what’s going on. Here’s an idea, though:

      • trash your emacs
      • download a fresh copy
      • launch it, then quit it
      • delete the code signature
      • launch it, then quit it. You may need to follow the steps in that Apple support link in order to do so.
      • finally, swap the correct binary in place of the Emacs launcher script
  • Paul M says:

    I can open any files, but dired (Ctrl-x d, or C-x C-f on a folder) still doesn’t work for any directory on my Mac. I get the dreaded “Listing directory failed but ‘access-file’ worked. (Dired works fine with remote tramp sessions.)

    • Paul M says:

      And the solution to that dired bug was to install coreutils and (setq insert-directory-program “/usr/local/bin/gls”), so that the dired-listing-switches from my linux machines work on Catalina.

  • Steve P says:

    Thank you Thank you Thank you Thank you!!!

    Now just to get rid of that big yellow triangle with the exclamation point which pops up every time a command fails…

  • Glenn K says:

    Thank you! This saved a lot time and tears… sometimes there’s a need to use emacs from the command line in a terminal, so I also created a little shell script so when I need to run it as sudo, for example, I can do that easily. This script also eliminates the annoying error message from the command line by sending it to /dev/null. Just place it somewhere on an appropriate path:
    ——————————————
    #!/bin/sh

    cd “${HOME}”

    /Applications/Emacs.app/Contents/MacOS/Emacs “$@” 2> /dev/null

  • Glenn K says:

    #!/bin/sh

    if [ -z “$1” ]; then
    cd “${HOME}”
    fi

    /Applications/Emacs.app/Contents/MacOS/Emacs “$@” 2> /dev/null

  • Paulus says:

    Thanks for this guide

    To get this to work with Emacs 27, I had to add `mv Emacs-x86_64-10_14.pdmp Emacs.pdmp` as a final step

  • Akira Okumura says:

    Does anyone know how to avoid this error when executing /usr/local/bin/emacs (symbolic link to /Applications/Emacs.app/Contents/MacOS/Emacs), which is created by Homebrew automatically? I followed the procedure in the original post and additional .pdmp procedure after installing 27.1 via Homebrew.

    $ /usr/local/bin/emacs
    Warning: arch-dependent data dir ‘/Users/build/workspace/Emacs-Multi-Build/label/macos10.14/emacs-source/nextstep/Emacs.app/Contents/MacOS/libexec/’: No such file or directory
    Warning: arch-independent data dir ‘/Users/build/workspace/Emacs-Multi-Build/label/macos10.14/emacs-source/nextstep/Emacs.app/Contents/Resources/etc/’: No such file or directory
    Warning: Lisp directory ‘/Users/build/workspace/Emacs-Multi-Build/label/macos10.14/emacs-source/nextstep/Emacs.app/Contents/Resources/lisp’: No such file or directory
    Error: /Users/build/workspace/Emacs-Multi-Build/label/macos10.14/emacs-source/nextstep/Emacs.app/Contents/Resources/etc/charsets: No such file or directory
    Emacs will not function correctly without the character map files.
    Please check your installation!

  • Thank you very much for this tutorial !! solved my problem in Catalina 10.15.7, I had to modify the third line with the replacement that you point in the comments.

    cd /Applications/Emacs.app/Contents/MacOS
    mv Emacs Emacs-launcher
    ln -s Emacs-x86_64-10_14 Emacs
    cd /Applications/Emacs.app/Contents/
    rm -rf _CodeSignature

  • Flip says:

    I couldn’t get my Emacs to do tab completion when running Find File. Just want to say that your solution is the only thing that worked after hours of googling the issue. Thank you so much!

  • Walt says:

    This solved my problem and just want to leave a THANK YOU! Cheers

  • Brad Lucas says:

    Thanks very much for the fix. Just upgraded to Catalina and it didn’t take long before I was in Emacs and couldn’t read ~/Downloads. Luckily your solutions was the first one I found and it did the trick. Appreciate that you posted this.

  • Don Colton says:

    Yay. This worked for me finally. And works for Big Sur. The secret sauce was
    cd /Applications/Emacs.app/Contents/MacOS
    mv Emacs Emacs-launcher
    # mv Emacs-x86_64-10_14 Emacs
    # what I did instead:
    ln -s Emacs-x86_64-10_14 Emacs
    cd /Applications/Emacs.app/Contents/
    rm -rf _CodeSignature

  • Max says:

    Can confirm that this works on Big Sur.

  • Carl says:

    You could just launch emacs from Terminal, no need to do all this. Besides, in case of Doom Emacs, messing with the launcher/script created unwanted consequences when running ‘doom’ commands.

  • Shota Senga says:

    Thanks for the article. This helped me to grant Emacs access Document. But there is one thing I had to do extra due to the error:

    “`
    desired fingerprint: 1513df07bd6374caad1e71fd3321d0b02c6a2ac4ef976a9c7c310ed7f101603e
    found fingerprint: d98de63f776b864bf82895da82cc6c25b802bedfd8798d0783f99fdac1263ecf
    emacs: could not load dump file “/Applications/Emacs.app/Contents/MacOS/Emacs.pdmp”: not built for this Emacs executable
    “`

    Overwriting the pdbmp file solved the issue.

    “`
    mv /Applications/Emacs.app/Contents/MacOS/Emacs-x86_64-10_14.pdmp /Applications/Emacs.app/Contents/MacOS/Emacs.pdmp
    “`

  • aes says:

    I can confirm Shota Senga, in addition to solution of Issue #2, I had to do the following:

    “`sh
    mv /Applications/Emacs.app/Contents/MacOS/Emacs-x86_64-10_14.pdmp /Applications/Emacs.app/Contents/MacOS/Emacs.pdmp
    “`

    macOS Catalina 10.15.7
    GNU Emacs 27.1 (build 1, x86_64-apple-darwin18.7.0, NS appkit-1671.60 Version 10.14.6 (Build 18G95))

    I installed emacs via brew `brew install –cask emacs` as described in the emacs wiki:
    https://www.emacswiki.org/emacs/EmacsForMacOS

  • Peter says:

    Awesome! This worked for me. Invested time: 5 seconds.

  • Martin Gregory says:

    You’re a genius finding the cause.

    There now seems to be a companion file called Emacs-x86_64-10_14.pdmp which you also have to rename to Emacs.pdmp … the existing Emacs.pdmp does not satisfy it (fingerprint mismatch).

    At least, this is the case for the Emacs I got from https://emacsformacosx.com/

  • Comments are closed.