Embed Subpaths
The problem
Embed syntax in Obsidian can include subpaths:
![[note]]— embed entire file![[note#Heading]]— embed a specific heading section![[note#^block-id]]— embed a specific block
In CachedMetadata.embeds, the link field contains the full text: "note#Heading" or "note#^block-id".
When resolving via getFirstLinkpathDest(link, sourcePath)1, passing the full subpath fails to resolve because getFirstLinkpathDest expects just the file path portion.
The fix
Use getLinkpath(embed.link) to strip the subpath before resolving:
import { getLinkpath } from "obsidian";
const linkpath = getLinkpath(embed.link);
// "note#Heading" → "note"
// "note#^block-id" → "note"
// "note" → "note"
const dest = app.metadataCache.getFirstLinkpathDest(linkpath, sourcePath);What this means for the embed index
The getFilesEmbedding method maps to the target file, not the specific heading or block. If note-a.md embeds ![[note-b#Heading]], then getFilesEmbedding("note-b.md") returns note-a.md.
There is currently no “which files embed heading X of file Y” query — only “which files embed file Y”.
Footnotes
-
MetadataCache.getFirstLinkpathDest — Obsidian Developer Docs — the
linkpathparameter is the path portion of a linktext, without subpath or display text. ↩