detect-transport: gate the CLI transport on this vault's reachability, not only on `obsidian version`

Author: cosmos75Created Jul 25, 2026Updated Sep 10, 2026

Summary

Every recipe in skills/wiki-cli/SKILL.md uses positional arguments (obsidian-cli read "$VAULT" "$NOTE"), but the Obsidian CLI shipped with Obsidian 1.12 takes named key=value arguments and targets vaults by name, not by path. The positional arguments are silently ignored, so the commands fall back to their "operate on the active file" default.

This matters because the failure is silent, not loud: a read returns content with exit 0, just from the wrong file in the wrong vault.

Tested on macOS 15 (Darwin 25.5.0), Obsidian 1.12.7, claude-obsidian v1.9.2 (cb93ff6).

Reproduction

The CLI is enabled via Settings → General → Advanced, which creates /usr/local/bin/obsidian symlinked to Obsidian.app/Contents/MacOS/obsidian-cli.

$ obsidian version
1.12.7 (installer 1.12.7)

$ obsidian --help
Usage: obsidian <command> [options]
Options:
  vault=<name>          Target a specific vault by name
Notes:
  file resolves by name (like wikilinks), path is exact (folder/note.md)
  Most commands default to the active file when file/path is omitted

Now the recipe form from skills/wiki-cli/SKILL.md, against a real vault path and a real note:

$ obsidian read "/Users/me/Projects/claude-obsidian" "wiki/concepts/Hot Cache.md"
---
title: Obsidian CLI

That is not Hot Cache.md. It is the active file of a different vault. Proof that both arguments are discarded:

$ obsidian read "/nonexistent/vault" "does/not/exist.md"
---
title: Obsidian CLI

$ obsidian file
path      Obsidian/Obsidian CLI.md
name      Obsidian CLI

A nonexistent vault plus a nonexistent note returns the same content as the apparently-valid request, exit 0 both times.

Why this is a data-safety issue, not just a docs bug

scripts/detect-transport.sh correctly detects the binary under either name (the elif command -v obsidian branch at line 131 works as intended), so on a machine with the CLI enabled transport.json becomes:

json
{"preferred": "cli", "fallback_chain": ["cli", "filesystem"]}

Every skill reads that file and routes writes through the CLI recipes. The CLI's command surface includes create, append, delete, and move. With positional arguments ignored, those resolve against the active file of whichever vault Obsidian currently has open — which in my case was a personal 288-note iCloud vault, not the project vault at all.

So enabling the CLI moves the vault from a working state (filesystem) to one where writes can land in an unrelated vault silently. I pinned transport.json back with manual_override: true as a workaround.

Second, related gap: binary presence is not vault reachability

A directory containing .obsidian/ that has never been opened in Obsidian is invisible to the CLI — the CLI only knows vaults registered in ~/Library/Application Support/obsidian/obsidian.json. My project vault had a full .obsidian/ directory (snippets, app.json with userIgnoreFilters) and was still unreachable.

detect-transport.sh currently treats "binary exists" as "CLI transport is usable." Those are different conditions. A probe such as obsidian files vault=<name> returning a non-empty listing for this vault would distinguish them.

Already-reported adjacent bug

I also hit the --version / version probe mismatch, but that is already #64 and I confirm it reproduces identically on macOS 1.12.7 (same error string in available.cli.version_string). Not repeating it here.

Suggested fixes

  1. Rewrite the wiki-cli recipes to named-argument form and vault-by-name targeting. For example obsidian read path="wiki/concepts/Hot Cache.md" vault=<name> rather than positional "$VAULT" "$NOTE". Worth verifying each command's exact parameter names against obsidian help <command>, since the namespaced forms in the skill (property:set, daily:today) also differ from what 1.12.7 lists (daily:read, daily:append, daily:prepend, daily:path).
  2. Gate preferred: cli on a vault-reachability probe, not just binary presence, and document that the vault must be registered in Obsidian.
  3. Consider having the recipes fail loudly when a target cannot be resolved, since the current default-to-active-file behaviour turns a mistake into silent wrong data.

Happy to send a PR for the recipe rewrite if that would help. I can only verify against 1.12.7 on macOS, so the exact parameter names should be checked on other CLI versions before merging.

Source: AgriciDaniel/claude-obsidian