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.
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"
endThis 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.
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.
Create ~/.config/fish/functions/obsidian.fish:
function obsidian
env -u XDG_RUNTIME_DIR /Applications/Obsidian.app/Contents/MacOS/Obsidian $argv
endAdd 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.
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.
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.