FAQ and Troubleshooting¶
A provider's status dot is red¶
The configured binary doesn't resolve or doesn't run (<bin> --version failed). Check:
- Is the CLI actually installed? A red dot most commonly just means it isn't.
- Is the binary path in Settings correct, or is it a bare command name that isn't on the
PATHObsidian sees? GUI apps on macOS don't always inherit your shell'sPATH— see Claude Code and OpenCode. - The dot only checks that the binary runs — it doesn't check login/auth. A green dot with a failing button usually means an auth problem, not a plugin problem; check the CLI's own login state directly (e.g.
claude doctor).
Claude Code fails with "--dangerously-skip-permissions cannot be used with root/sudo privileges"¶
Claude Code's own CLI refuses that flag when the process runs as root — this happens if Obsidian itself is running as root (common in some container setups). It's a Claude Code safety restriction, not something the plugin can route around. Either run Obsidian as a non-root user, or turn off auto-approve for that button and approve tool calls manually in the terminal.
A button's model: value doesn't seem to do anything¶
Check that the mapping name you typed matches one configured under the agent that button actually resolves to — mappings are scoped per provider, so a Claude Code mapping named quick isn't visible to a button using agent: OpenCode. If nothing matches, the value is passed straight through as a literal model string, which most CLIs reject as unknown if it isn't a real model ID — see Model Mappings.
A {{= }} expression does nothing / errors¶
{{= }} expressions are off by default. Turn on Allow JavaScript expressions in prompts in Settings — see Context and Templating. While off, a button whose prompt contains {{= }} writes a clear error to the terminal instead of running.
A {{ }} lookup shows up literally in the sent prompt instead of being replaced¶
That means the root name wasn't recognized (a typo like {{flie.basename}}) — this is deliberate, so the mistake stays visible rather than silently vanishing. Check the spelling against the Context Reference. A missing value under a real root (e.g. no frontmatter status field) renders as an empty string instead, which looks different from this case.
The plugin needs python3 — is that a problem?¶
The terminal is allocated via python3 -c "import pty,sys; pty.spawn(sys.argv[1:])" rather than a native node-pty build, specifically to avoid needing a fresh native prebuild every time Obsidian's bundled Electron version changes. This needs a python3 at one of a few standard locations, or on PATH — true on basically any Mac or Linux environment already. If it's genuinely missing, install Python 3 for your OS and it'll be picked up.
An earlier attempt used BSD script -q /dev/null, which is broken specifically when Obsidian spawns it (script: tcgetattr/ioctl: Operation not supported on socket) — this is why python3 is used instead, not script.
Other things worth knowing¶
- Binary path resolution is best-effort, not exhaustive — an unusual install location may need to be set explicitly in Settings.
agentOutput: fileandcompletion: responseEndare both heuristic, pattern-matching the rendered terminal against text Claude Code has been observed to print — a CLI update or unusual output can occasionally misclassify a run. See Completion Modes and Captured File Output.- Closing the note kills a
manual-mode run. Each button's process is tied to its block's lifetime — navigating away sends the child processSIGINT. AresponseEndrun does outlive the button going idle, but not the note being closed. - No live terminal resize signal to the child — a long run in a pane you resize mid-flight may wrap oddly, but content still comes through correctly.
- One button = one fixed workflow. There's no dropdown/picker for choosing a prompt at click time; each block is one hardcoded (templated) prompt.
Still stuck?¶
Open an issue on GitHub with what you tried and what happened.