On macOS, editing any note whose filename is stored in Unicode NFD (decomposed) form removes that note from the file explorer, search, and the vault index, even though the file still exists on disk. Restarting Obsidian brings the note back (full rescan); editing it again makes it disappear again. 100% reproducible per file.
This is a regression: 1.13.4 is not affected; 1.13.6 is affected (verified by diffing the two app bundles, see analysis below). Other reports suggest it started in 1.13.5.
This hits vaults with Korean/Japanese/accented filenames especially hard: files created by Obsidian itself get NFC names (so most users never see this), but files migrated from other tools, created in Terminal, checked out via git, or dating back to HFS±era macOS are commonly NFD. In my vault (migrated from Logseq), essentially every Korean-named note is NFD, so every one of them vanishes on edit under 1.13.5+.
Steps to reproduce
-
On macOS (default case-insensitive APFS), quit Obsidian and create a file with an NFD-form name inside a vault, e.g.:
cd /path/to/vault python3 -c "import unicodedata; open(unicodedata.normalize('NFD','café') + '.md','w').write('hello')" -
Open Obsidian 1.13.5 or 1.13.6. The note
café.mdappears in the file explorer and search.
-
Open the note and type a few characters (any change that triggers a save).
Did you follow the troubleshooting guide? Y
Expected result
The note stays in the file explorer and remains searchable.
Actual result
Within a couple of seconds of the save, the note disappears from the file explorer and search. The file is untouched on disk. Restarting Obsidian restores it; editing reproduces the disappearance every time.
I reproduced this with restricted mode on; the root cause is in the core desktop filesystem watcher (below), so plugins and themes are not involved.
Environment
Observed on macOS 26 / Apple Silicon, Obsidian 1.13.6, installer 1.13.4, restricted mode on. Currently rolled back to 1.13.4, where the bug does not occur.
Additional information
Root cause analysis (from the shipped code)
In the desktop filesystem adapter, reconcileFile(e, t) receives e = the raw watcher event path and t = the NFC-normalized vault path. On case-insensitive filesystems (this.insensitive, always true on default macOS APFS) it verifies the file still exists by reading the parent directory and searching for the basename.
1.13.6 (from obsidian-1.13.6.asar, minified):
r=this.getFullRealPath(e),this.insensitive?(o=this.path.dirname(r),
a=this.path.basename("/"!==e?e:this.basePath), // needle: RAW event path
[4,this.fsPromises.readdir(o)]):[3,7];
case 5:return-1!==l.sent().map(function(e){return Dl(e).normalize("NFC")}) // listing: NFC-normalized
.indexOf(a)?[3,7]:[4,this.reconcileDeletion(e,t,n)];
1.13.4 (from the installer’s bundled obsidian.asar, minified):
r=this.getFullRealPath(e),this.insensitive?(o=this.path.dirname(r),
a=this.path.basename(t), // needle: NFC-normalized path
[4,this.fsPromises.readdir(o)]):[3,7];
case 5:return-1!==l.sent().map(function(e){return Sl(e).normalize("NFC")})
.indexOf(a)?[3,7]:[4,this.reconcileDeletion(e,t,n)];
Dl/Sl are the same whitespace-cleanup helper in both versions; the only functional change is the needle source: basename(t) (normalized) → basename(e) (raw).
On macOS, fs.watch (FSEvents) reports filenames in their on-disk byte form — NFD for NFD-named files. So in 1.13.5/1.13.6 the needle is an NFD string, the directory listing has been normalized to NFC, indexOf can never match, and reconcileDeletion() is invoked for a file that exists. In 1.13.4 both sides are NFC and the check passes.
Standalone repro of the failing comparison (no Obsidian needed)
// node repro.js /path/to/some/dir — macOS only
const fs = require('fs');
const dir = process.argv[2] || '.';
const nfd = dir + '/' + 'café'.normalize('NFD') + '.md';
fs.writeFileSync(nfd, 'probe\n');
fs.watch(dir, { encoding: 'utf8' }, (ev, fn) => {
if (!fn || !fn.normalize('NFC').includes('café')) return;
const list = fs.readdirSync(dir).map(x => x.normalize('NFC'));
console.log('event filename form :', fn === fn.normalize('NFC') ? 'NFC' : 'NFD');
console.log('1.13.6-style check :', list.includes(fn) ? 'found' : 'MISS -> reconcileDeletion');
console.log('1.13.4-style check :', list.includes(fn.normalize('NFC')) ? 'found' : 'MISS');
});
// simulate Obsidian saving through its NFC-canonical path
setTimeout(() => fs.appendFileSync(dir + '/' + 'café'.normalize('NFC') + '.md', 'edit\n'), 500);
setTimeout(() => { fs.unlinkSync(nfd); process.exit(0); }, 2500);
Output on macOS (APFS resolves the NFC path to the existing NFD file; the event reports the on-disk NFD name):
event filename form : NFD
1.13.6-style check : MISS -> reconcileDeletion
1.13.4-style check : found
Suggested fix
Normalize the needle the same way as the listing — e.g. keep the new base-path guard but derive the needle from the normalized path (basename(t), as in 1.13.4), or apply the same Dl(...).normalize("NFC") to the needle before the indexOf.
Workaround for affected users
Quit Obsidian, delete the downloaded update (~/Library/Application Support/obsidian/obsidian-1.13.*.asar) to fall back to the installer’s 1.13.4, and disable automatic updates until this is fixed. Confirmed to stop the disappearances in my vault (thousands of NFD-named notes).