Steps to reproduce
- On Windows, ensure the latest installer (the CLI runs via the bundled
Obsidian.com— the Windows console-host binary shipped next toObsidian.exe, not a website). Open a vault. - Create ~200 dummy attachments in a folder
_src/. - Fire
obsidian movefor all of them concurrently (so calls arrive faster than the app drains them):
for f in _src/*; do obsidian move path="$f" to="_dst" & done; wait - Count how many actually moved to
_dst/.
Reliable (large-vault) variant that also triggers the wedge:
- In a larger vault (heavier per-move reindex), fire a few hundred
obsidian movesequentially but fast (e.g. each call inside$(...)so its output is consumed and the shim returns before the move completes). - After the burst, run a few SINGLE, well-spaced
obsidian movecommands.
Did you follow the troubleshooting guide?
Yes. Reproduced in the Sandbox vault with Restricted mode on (0 community plugins) on the latest version.
Expected result
Every move either succeeds (file relocated, links updated) or prints an error and returns non-zero. The handler keeps working for subsequent commands.
Actual result
- A fraction of concurrently-fired moves return exit code 0, no stdout, no error — and the file is NOT moved (silent no-op). In the clean Sandbox this is intermittent (~1–2% under one concurrent burst); in a large vault it is severe.
- In a large vault, after a sustained fast burst the
movehandler stops responding entirely: even single, well-spacedmovecalls become silent no-ops (empty output, exit 0, nothing moved). It only recovers afterobsidian reload+ ~30s. - Read-only commands (
backlinks,unresolved,version) keep working throughout — only the mutating handler degrades. - The failure is load/timing-dependent: it appears when
movecommands arrive faster than the app processes them. Sequential firing in a small vault self-throttles (per-call latency grows with vault size) and does not drop, which is likely why earlier reports were marked resolved. - Secondary: CLI stdout is empty when output is redirected to a file or captured via command-substitution; it prints reliably only on an interactive TTY — so scripts get no success/failure signal (compounded by exit 0 on failure).
Environment
- Obsidian 1.12.7 (installer 1.12.7), CLI via
Obsidian.com. - Windows 11.
- Reproduced in the Sandbox vault: Restricted mode on, community plugins enabled = 0.
Additional information
Likely the same IPC/named-pipe dispatch cluster as:
- CLI console shim silently fails on colon subcommands with key=value parameters (named-pipe layer dropping commands; “fixed 1.12.2”)
- CLI: Each obsidian move CLI command spawns a new full Electron/Obsidian app instance (move silently fails / no exit)
- CLI: `property:set` Silently Succeeds But Makes No Change on Externally-Written Files (silent no-op via in-memory IPC state)
- Obsidian CLI: Make Return Value / Exit Code reflect the success/fail state of the operation performed (exit code 0 on failure)
New vs. those threads: the wedge-until-reload behaviour (severe in large vaults), the explicit load/timing-dependence (sequential firing self-throttles and passes), and the TTY-only-stdout / empty-on-redirect behaviour.
Hypothesis (closed-source app, so speculative): the shim fires-and-exits without awaiting the async rename; commands arriving faster than the queue drains are dropped, and in a large vault a backlog wedges the handler until a reload resets it.
Suggested fix: add backpressure/acknowledgement so each move blocks until the rename resolves (or errors and returns non-zero), plus reliable non-TTY stdout.
Sandbox reproduction (verified)
Clean Sandbox vault, Restricted mode, 0 community plugins, Obsidian 1.12.7:
- Created 200 dummy files in
_src/, target folder_dst/. - Sequential fast-fire (200): 200/200 moved, all printed
Moved:— no drops. (Small vault drains faster than the shell fires.) - Concurrent fire (200 backgrounded at once): 197/200 moved, 3 silently dropped — the 3 stayed in
_src/with no error emitted. A paced retry of a dropped file then succeeded (handler not wedged at this scale). - Repeats of the concurrent burst were inconsistent (0 drops on some runs) — the drop is timing-sensitive.
- Bloated with several thousand extra notes + sequential fast-fire: 0 drops — the larger vault raised per-call latency, self-throttling the fire rate below the drop threshold.
- The handler wedge (all moves no-op until
reload) did not reproduce in the Sandbox; it only occurred in a larger vault (below).
Supporting evidence (larger-vault run that first surfaced this)
- A bulk job moved a few hundred files between folders in a much larger vault by firing
obsidian movein a fast loop. - Net result: only a minority moved; the remainder silently no-op’d (exit 0, empty output, file not moved). Afterwards even single paced
movecalls no-op’d untilobsidian reload+ ~30s. - Post-recovery, paced moves worked 100% (verified across repeated batches). Confirms the rate/wedge dependence.