Nermal
Reference

Troubleshooting

The things that go wrong, and what they actually mean.

Start here

Nermaldoctor

One table: whether the server is reachable, whether its wire dialect matches your binary, the three environment variables, pid/uptime/panes, and how many machine links exist. Most of what follows is a specific answer this gives you.

Nermal: command not found

The CLI is put on PATH the first time the app launches. If it is missing:

  • Check Settings → Agents → Install the Nermalcommand on PATH is on.
  • On Unix it symlinks into whichever of /opt/homebrew/bin, /usr/local/bin, ~/.local/bin, ~/bin, ~/.cargo/bin your PATH already covers — if none of those are on your PATH, add one.
  • On Windows the install directory is appended to your user PATH, which needs a new shell to take effect.
  • A Nermal you installed yourself is never replaced, so an old one earlier in PATH will win.

Inside a Nermalpane it works regardless, since panes inherit the app's environment.

The server is unreachable

Nermaldoctor says so, and the GUI cannot open panes.

Start it with Nermalserver start. If you are an agent or a script, do not — tell the user instead. Starting a server they did not ask for changes what their GUI attaches to.

For logs:

Nermal_LOG=info   # must be set before the server starts
Nermalserver logs

Panes came back empty

A crash, a kill -9, or a reboot takes the shells with it — that part is unavoidable. The screens should come back: Nermalkeeps a capped tail of each pane's output (256 KiB) and hands it to the pane that reopens on that id.

It is consumed once. If a pane was restored, then closed, then reopened, the second time there is nothing left to restore — that is by design, not a bug.

"The background server is still running <build>"

Nermalupdated in place, so the app is new and your panes are still served by the previous build. Restarting the server picks up the new one and ends every process in every pane. There is no hurry — do it when your panes are idle. Updates →

A remote machine will not connect

MessageWhat it means
"running an old Nermalserver that this copy cannot talk to"The server there predates your client's protocol. Let Nermalupdate it — this ends every session on that machine.
"running a newer Nermalserver than this copy"Update Nermalhere instead, or replace the server there.
"answered, but not as a Nermalserver"Something else is listening, or the binary is not what Nermalexpects.
"Nermalno longer has a way to reach <machine>"The SSH link dropped. Reconnect from the switcher.

Nermal-m <machine> never dials a fresh connection by design — it uses a link the local server already holds. Connect from the GUI first.

⇥ or ⌃ R is not doing what I expect

Both are switches, and turning one off hands the key straight back to your shell:

  • Settings → Input → Prompt → Tab completion
  • Settings → Input → Prompt → History search

If they do nothing at all in a particular pane, the shell there probably has no shell integration — elvish, xonsh and friends run fine but do not get the prompt layer.

The directory stopped following my shell

The Files panel, new splits, and the sidebar's repo grouping all follow the directory the pane's shell reports (OSC 7). If the pane is frozen on one directory while you cd around, something in the pane is not reporting it.

The usual cause is a shell you started by hand. Nermalinjects its shell integration into the shell it launches for the pane, and nothing else: run zsh at a bash prompt and that nested shell has none. Locally you rarely notice, because oh-my-zsh reports the directory itself — but the cwd reporter sits at the end of its lib/termsupport.zsh, behind

if [[ -n "$INSIDE_EMACS" || -n "$SSH_CLIENT" || -n "$SSH_TTY" ]]; then
  return
fi

so over SSH, where sshd sets those, sourcing stops there and the reporter is never defined — only the title hooks above that line still run. A nested zsh on a remote host therefore reports nothing, from either side, and the pane keeps showing wherever the outer shell was.

Make it the shell Nermalstarts. On the remote host:

chsh -s /bin/zsh      # then reconnect

Nermalasks the host for $SHELL at connect time and bootstraps that shell, so this is what moves the integration into your zsh — oh-my-zsh keeps working beside it. Starting zsh from a login script, or exec zsh from your .bashrc, does not help: both run after (or instead of) the shell Nermalset up.

Or report the directory yourself. If you cannot change the login shell, add this to the remote ~/.zshrc — it restores directory tracking only, not prompt marks or command status:

# Report the working directory to Nermal(OSC 7).
autoload -Uz add-zsh-hook
__Nermal_cwd() { printf '\e]7;file://%s%s\a' "${HOST:-localhost}" "${PWD//\%/%25}" }
add-zsh-hook precmd __Nermal_cwd

It is safe to leave in place afterwards: when Nermalis integrating that shell, the two hooks simply report the same directory twice. The bash equivalent is PROMPT_COMMAND:

__Nermal_cwd() { printf '\e]7;file://%s%s\a' "${HOSTNAME:-localhost}" "${PWD//%/%25}"; }
PROMPT_COMMAND="__Nermal_cwd${PROMPT_COMMAND:+;$PROMPT_COMMAND}"

Two other reasons a pane never reports its directory:

  • The shell is not one Nermalintegrates. It injects into zsh, bash, fish, PowerShell and nushell locally, and into zsh, bash and fish over SSH — a remote host whose $SHELL is anything else gets no bootstrap, silently.
  • You gave the shell your own arguments in shell or a custom_shells entry, which turns the injection off by design.

Where Nermalcan see the pane's processes it falls back to reading the foreground process's working directory, which is why an unintegrated shell in a remote workspace mostly keeps up — that fallback is a poll, though, sampled while the pane produces output, so it can lag a cd until the pane writes again. There is no such fallback for an SSH pane (the processes are on the far end) or for a local pane on Windows.

⌥ B types ∫ instead of moving a word

That is macOS's default. Turn on Settings → Input → Keyboard → Option (⌥) acts as Meta.

CJK characters have a gap on the right

Your CJK fallback advances 1.0em while the primary face advances 0.60205em, so the glyph does not fill its two-column slot. Install Maple Mono NF CN — it is already first in the fallback chain and fits Hack exactly — or change the primary face. The full explanation →

A theme in my themes folder is not showing up

Settings lists it under Not loaded from the themes folder, with the reason. Usually a missing required key: background, foreground, accent, and ansi (with eight normal and eight bright entries) are all mandatory.

My config.json edits did nothing

If the file cannot be parsed, Nermalstarts on defaults and keeps your original at config.json.corrupt — check for that file. Otherwise:

  • An out-of-range number is clamped, not applied literally.
  • An unrecognised enum value falls back to the default with a log line.
  • scrollback_limit applies to new panes only.
  • An unknown action name in keybindings is skipped with a warning.

Selecting text inside vim / less selects the app's own thing

Hold ⇧ while dragging to keep the gesture local, or turn off Settings → Terminal → Mouse → Report mouse to apps.

Nermalcapture … | head -1 printed a Rust panic

An old build's behaviour when the reader hangs up. The data you asked for still arrived. On such a build, redirect to a file and slice the file instead of piping into head. Current builds exit 141 on Unix, which is exactly what cat does.

Still stuck

Sponsor