CLI: unrecognised arguments are silently discarded, so a mistyped query returns another note's data

Steps to reproduce

The one-command version, which needs no fixture and no setup — with Obsidian running and CLI support enabled, in any vault, with any note open:

obsidian backlinks --help

It prints the active note’s backlinks. A --help flag is consumed as though it were not there.

The full version, which shows the consequence:

  1. Create a new empty vault with four notes:

    • A.mdlinks to [[Target]] and [[sub/Deep]]
    • B.mdalso links to [[Target]]
    • Target.md and sub/Deep.md — any content

    Ground truth: Target.md has two inbound links (A, B); sub/Deep.md has one (A).

  2. Enable Settings → General → CLI support, leave Obsidian running with this as the only open vault.

  3. Click Target.md so it is the active note. (The behaviour below depends on which note is active.)

  4. Run:

obsidian backlinks path="sub/Deep.md"   # correct keyword form
obsidian backlinks pat="sub/Deep.md"    # one-character typo of path=
obsidian backlinks foo=bar              # unrecognised keyword
obsidian backlinks --help               # a flag
obsidian backlinks "sub/Deep.md"        # positional (undocumented form)

Did you follow the troubleshooting guide? [Y]

Reproduced in a fresh vault with Restricted mode on from first launch, no community theme, 0 CSS snippets, app and installer both 1.12.7 — see the Environment block. No plugins were ever installed in this vault. Not the Sandbox Vault specifically, but equivalent or stricter on every item in the guide.

Expected result

An argument the parser does not recognise should produce an error naming the expected form — the way path= on a missing file and an unknown command already do. It should not be discarded.

Actual result

Every unrecognised argument is dropped, after which the command falls through to the documented active-file default and answers about Target.md:

$ obsidian backlinks path="sub/Deep.md"    →  A.md               correct
$ obsidian backlinks pat="sub/Deep.md"     →  A.md   B.md        wrong — Target.md's backlinks
$ obsidian backlinks foo=bar               →  A.md   B.md        wrong
$ obsidian backlinks --help                →  A.md   B.md        wrong — a flag, answered with data
$ obsidian backlinks "sub/Deep.md"         →  A.md   B.md        wrong

The typo case is the practical one. pat= instead of path= is a single character, and the result is not an error but a plausible, non-empty answer about a different note. Nothing distinguishes it from a correct result.

sub/Deep.md makes this checkable: it genuinely has one inbound link, the correct keyword form returns exactly that, and every mistyped variant returns a different note’s two.

The argument does reach the application — the log records Received command line [ 'backlinks', 'zzzzz' ] — so this is the subcommand’s option parsing discarding what it does not recognise, not the argument being lost in transit.

Secondary symptom. With no note active (immediately after opening a vault, before clicking any note), the same unrecognised forms return No backlinks found. instead. The correct keyword form is unaffected and still returns the right answer in that state — which is what shows the defect is in argument handling rather than in the link index. So the same fault yields a false negative with nothing focused and a false positive with the wrong note focused.

On exit codes: this CLI appears not to use them — path= on a missing file prints Error: File "…" not found. and an unknown command prints Error: Command "…" not found., both at exit 0. So the ask above is for an error message, consistent with existing behaviour, not a change to exit status.

Environment

SYSTEM INFO:
    Obsidian version: 1.12.7
    Installer version: 1.12.7
    Operating system: #28-Ubuntu SMP PREEMPT_DYNAMIC Sun Jun 21 01:01:36 UTC 2026 7.0.0-28-generic
    Login status: not logged in
    Language: en-GB
    Insider build toggle: off
    Live preview: on
    Base theme: adapt to system
    Community theme: none
    Snippets enabled: 0
    Restricted mode: on

RECOMMENDATIONS:
    none

Additional information

Duplicate search: searched the forum for prior reports on the CLI backlinks subcommand — four keyword queries (backlinks CLI, obsidian-cli backlinks, CLI positional argument, No backlinks found). Hits were backlinks-pane topics and unrelated plugins only. Not an exhaustive read of the category.

Why this matters beyond a usage error. Anything scripting vault maintenance — link-integrity checks, safe-move verification, orphan detection — treats a backlinks result as authoritative. A mistyped argument silently returning a different note’s links means such a script can conclude a note has no inbound links, or the wrong ones, and act on it. Nothing in the output indicates the query it asked was never run.

Suggested fix: reject unrecognised arguments — positional, mistyped keyword, or flag — with an error naming the expected path= / file= form.

Test environment, in full. This machine restricts unprivileged user namespaces, so the official AppImage will not start as shipped (FATAL … The SUID sandbox helper binary was found, but is not configured correctly). It was therefore run extracted (--appimage-extract) and launched as:

squashfs-root/obsidian --no-sandbox --ozone-platform=x11

with a non-default --user-data-dir for the throwaway config. Listing all of it rather than just the sandbox flag, since none of it should matter and it is cheap to state. The mechanism: obsidian-cli is a separate small binary that forwards argv to the running app over a UNIX socket under the user-data dir, and the app log confirms it arrives intact — so extraction, the sandbox flag and the renderer platform are all downstream of, and irrelevant to, the subcommand’s option parser. One Obsidian instance and one vault were involved in these results; no vault= argument was passed.

Note on the binary name: the help string names the program obsidian; on this install the CLI ships alongside the app as obsidian-cli. Commands above use the name from the help output.