Skip to content

Instantly share code, notes, and snippets.

@galligan
Created March 7, 2026 03:50
Show Gist options
  • Select an option

  • Save galligan/fd619fd05da2abcd99a05ba59dc85182 to your computer and use it in GitHub Desktop.

Select an option

Save galligan/fd619fd05da2abcd99a05ba59dc85182 to your computer and use it in GitHub Desktop.
Fix: Obsidian CLI "Unable to connect to main process" on macOS

Fix: Obsidian CLI "Unable to connect to main process" on macOS

If you're getting this error when running obsidian commands from the terminal:

Unable to connect to main process

...even though Obsidian is open, here's what's happening and how to fix it.

Root Cause

The Obsidian CLI works by connecting to the running Obsidian app via a Unix socket. When Obsidian launches (from the GUI, Dock, or Spotlight), it creates that socket at:

~/obsidian-cli.sock

It picks this path using the following logic (from the Obsidian source):

const socketPath = path.join(process.env.XDG_RUNTIME_DIR || os.homedir(), 'obsidian-cli.sock');

Since Obsidian launches as a GUI app — not from the terminal — it doesn't inherit shell environment variables. XDG_RUNTIME_DIR is unset, so it falls back to homedir() and creates the socket at ~/obsidian-cli.sock.

When you run obsidian from the terminal, the CLI binary uses the same path resolution. But on macOS, many shell configs (including common fish setups) set XDG_RUNTIME_DIR as a compatibility shim:

# ~/.config/fish/conf.d/env.fish
if not set -q XDG_RUNTIME_DIR
    set -gx XDG_RUNTIME_DIR "$TMPDIR"
end

This sets XDG_RUNTIME_DIR to something like /var/folders/xx/xxxx/T/. Now the CLI binary looks for the socket at:

/var/folders/xx/xxxx/T/obsidian-cli.sock

...which doesn't exist. The real socket is at ~/obsidian-cli.sock. Connection fails, and you get the error.

The Fix

Create a shell function that clears XDG_RUNTIME_DIR before invoking the CLI, so it finds the socket at the same path the GUI app created it.

There's also a secondary issue: the Homebrew cask creates a symlink at /opt/homebrew/bin/obsidian pointing into the .app bundle, but calling that symlink from outside the bundle context causes a separate Unable to find helper app error. The fix is to invoke the binary directly from inside the bundle.

fish

Create ~/.config/fish/functions/obsidian.fish:

function obsidian
    env -u XDG_RUNTIME_DIR /Applications/Obsidian.app/Contents/MacOS/Obsidian $argv
end

zsh / bash

Add to ~/.zshrc or ~/.bashrc:

obsidian() {
    env -u XDG_RUNTIME_DIR /Applications/Obsidian.app/Contents/MacOS/Obsidian "$@"
}

Open a new terminal and obsidian help should now work.

Why XDG_RUNTIME_DIR Gets Set on macOS

XDG_RUNTIME_DIR is a Linux standard (part of the XDG Base Directory Specification) that defines a per-user runtime directory for sockets, pipes, and temporary files. macOS doesn't set it natively, but many tools (D-Bus, systemd ports, pipx, etc.) expect it to exist. Shell configs often set it to $TMPDIR as a compatibility shim — which is usually harmless, but trips up any app that uses it to locate a socket that was created without it.

Affected Versions

Confirmed on Obsidian 1.12.4 / 1.12.5 on macOS. Likely affects any macOS setup where XDG_RUNTIME_DIR is set in the shell environment.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment