Hi all — I’m running into a persistent issue with a Templater script that inherits tags from a root note. Here’s the behavior:
What I’m trying to do
- If no root note exists, it creates one with a YAML block and the tag
rootx
. - If a root note with
rootx
exists, it reads the tags from the root note’s YAML frontmatter and creates a child note inheriting those tags.
The script:
<%*
const sanitize = str => str.replace(/[\\/:*?"<>|]/g, "").trim();
const toYamlList = arr => `[${arr.join(", ")}]`;
await new Promise(r => setTimeout(r, 300));
const files = app.vault.getMarkdownFiles();
let rootNote = null;
let rootTags = [];
for (const file of files) {
const content = await app.vault.read(file);
const match = content.match(/^---\n([\s\S]*?)\n---/);
if (!match) continue;
const yamlBlock = match[1];
const lines = yamlBlock.split("\n");
let tags = [];
let isMultiline = false;
for (let line of lines) {
const trimmed = line.trim();
if (trimmed.startsWith("tags:") && trimmed.includes("[")) {
tags = trimmed
.split(":")[1]
.replace(/[\[\]]/g, "")
.split(",")
.map(t => t.trim())
.filter(Boolean);
break;
}
if (trimmed === "tags:") {
isMultiline = true;
continue;
}
if (isMultiline) {
if (trimmed.startsWith("- ")) {
tags.push(trimmed.slice(2).trim());
} else {
break;
}
}
}
if (tags.includes("rootx")) {
rootNote = file;
rootTags = tags;
break;
}
}
if (!rootNote) {
const title = await tp.system.prompt("No root note found. Enter root note title:");
const filename = `Root - ${sanitize(title)}`;
const yamlBlock =
`---
title: ${title}
tags: [rootx]
---`;
await tp.file.create_new(yamlBlock, filename, true);
tR = `✅ Created root note "${filename}" with tag [rootx]`;
return;
}
const childTitle = await tp.system.prompt("Enter child note title:");
const childFilename = `Child - ${sanitize(childTitle)}`;
const childYaml =
`---
title: ${childTitle}
tags: ${toYamlList(rootTags)}
---`;
await tp.file.create_new(childYaml, childFilename, true);
tR = `✅ Created child note "${childFilename}" with inherited tags: ${toYamlList(rootTags)}`;
%>
The Issue
This script only inherits saved tags from the root note if I:
- Restart Obsidian after editing the root note’s YAML
- Then run the template
If I just edit the root note (e.g., add a tag manually in YAML) and then run the script:
- The child note is created
- But it only contains the old set of tags — new ones are not picked up
Things I have tried
- Reading the file with
app.vault.read(rootNote)
(assumed to read from disk) - Using
window.jsyaml
(breaks — not available in my environment) - Using
metadataCache.getFileCache(file)
(doesn’t reflect recent edits) - Forcing a delay (
setTimeout
) to allow disk writes to flush - Opening the root note programmatically to trigger update
- Reading from the editor via
MarkdownView
(throwsundefined
in Templater) - Confirmed note is saved and open
What I Suspect
Obsidian holds file content in memory, and Templater reads the version from disk — which may lag behind unless Obsidian is restarted (or possibly if the file is closed and reopened). But I haven’t found a reliable way to force a sync from memory to disk before reading the file inside a Templater script.
What I Need Help With
- Is there any way in Templater to reliably access the in-memory YAML of another note (not the one the script is running in)?
- Can I force Obsidian to save the note or flush it to disk before reading?
- Or is this a known limitation that requires user manual intervention (save file + restart)?
Environment
- Obsidian: v1.8.9
- Templater: 2.11.1 latest community version
- OS: Win 11 x64
Any insight is hugely appreciated.
Happy to test any code or file setup — just want to reliably inherit YAML tags from a root note without restarting Obsidian every time.
Thanks so much!