With a rule that has "Show in popover views" enabled, virtual content never appears in hover popovers, even though it renders correctly when the note is opened normally. This reproduces 100% of the time.
Debug steps taken:
First pass — checking the popover DOM immediately on creation via MutationObserver:
const _vcDebugObs = new MutationObserver(() => {
document.querySelectorAll('.popover.hover-popover').forEach(p => {
if (p.dataset.vcLogged) return;
p.dataset.vcLogged = "1";
console.log("inline-title:", p.querySelector('.inline-title')?.textContent ?? "(none found)");
console.log("markdown-embed present:", !!p.querySelector('.markdown-embed'));
console.log("header group injected:", !!p.querySelector('.virtual-footer-header-group'));
});
});
_vcDebugObs.observe(document.body, { childList: true, subtree: true });
Result: inline-title: (none found), markdown-embed present: true, header group injected: false.
Second pass — same check, but delayed 400ms after the popover element first appears:
const _vcDebugObs2 = new MutationObserver(() => {
document.querySelectorAll('.popover.hover-popover').forEach(p => {
if (p.dataset.vcLogged2) return;
p.dataset.vcLogged2 = "1";
setTimeout(() => {
console.log("inline-title:", p.querySelector('.inline-title')?.textContent ?? "(none found)");
console.log("markdown-embed is-loaded:", !!p.querySelector('.markdown-embed.is-loaded'));
console.log("header group injected:", !!p.querySelector('.virtual-footer-header-group'));
}, 400);
});
});
_vcDebugObs2.observe(document.body, { childList: true, subtree: true });
Result: inline-title: 2026-08-24, markdown-embed is-loaded: true, but header group injected: false — still nothing, even though the title is now present and correctly resolvable to the file.
I also captured the full popover HTML at a settled state (via DevTools) — .inline-title is present with the correct text, frontmatter/properties are fully rendered, and .markdown-embed has the is-loaded class. So the popover content itself, and the underlying file resolution (.inline-title → getFirstLinkpathDest()), both work fine given enough time. The failure seems to be about when the plugin checks.
Root cause:
The plugin schedules a popover check using a short, fixed, one-shot delay with no retry/polling:
mouseover on a.internal-link → checks after 100ms
MutationObserver on .popover.hover-popover being added → checks after 50ms
- click inside popover (mode-switch handling) → checks after 150ms
In my environment, .inline-title doesn't populate until noticeably later (>150ms, closer to 300-400ms) after the popover element is first added to the DOM. Since none of these checks retry, they all fire and read an incomplete DOM, extract no file path, and injectContentIntoPopover() never runs. This also explains why hovering the same link a second time didn't help — both hovers raced against the same too-short delay and lost the same way.
Suggested fix:
Replace the fixed-delay one-shot checks with either:
- A short polling loop (e.g. check every ~50ms up to a ~1000ms cap) for
.inline-title having non-empty text or .markdown-embed having the is-loaded class, before giving up, or
- A
MutationObserver scoped specifically to the popover element itself, resolving once .inline-title text is non-empty, rather than relying on the outer document-level observer's single fire-and-forget timeout.
- Resolving the file via the hovered link's own
data-href attribute (already captured in this.lastHoveredLink on the mouseover handler) instead of round-tripping through the popover's rendered title text would sidestep this whole timing dependency, since data-href is available immediately on hover, before the popover even starts rendering.
Environment:
- Virtual Content: v1.0.38
- Render location: Header
- "Render above properties": off
- Obsidian: 1.13.7
- OS: Mac Tahoe 26.6ob
With a rule that has "Show in popover views" enabled, virtual content never appears in hover popovers, even though it renders correctly when the note is opened normally. This reproduces 100% of the time.
Debug steps taken:
First pass — checking the popover DOM immediately on creation via
MutationObserver:Result:
inline-title: (none found),markdown-embed present: true,header group injected: false.Second pass — same check, but delayed 400ms after the popover element first appears:
Result:
inline-title: 2026-08-24,markdown-embed is-loaded: true, butheader group injected: false— still nothing, even though the title is now present and correctly resolvable to the file.I also captured the full popover HTML at a settled state (via DevTools) —
.inline-titleis present with the correct text, frontmatter/properties are fully rendered, and.markdown-embedhas theis-loadedclass. So the popover content itself, and the underlying file resolution (.inline-title→getFirstLinkpathDest()), both work fine given enough time. The failure seems to be about when the plugin checks.Root cause:
The plugin schedules a popover check using a short, fixed, one-shot delay with no retry/polling:
mouseoverona.internal-link→ checks after 100msMutationObserveron.popover.hover-popoverbeing added → checks after 50msIn my environment,
.inline-titledoesn't populate until noticeably later (>150ms, closer to 300-400ms) after the popover element is first added to the DOM. Since none of these checks retry, they all fire and read an incomplete DOM, extract no file path, andinjectContentIntoPopover()never runs. This also explains why hovering the same link a second time didn't help — both hovers raced against the same too-short delay and lost the same way.Suggested fix:
Replace the fixed-delay one-shot checks with either:
.inline-titlehaving non-empty text or.markdown-embedhaving theis-loadedclass, before giving up, orMutationObserverscoped specifically to the popover element itself, resolving once.inline-titletext is non-empty, rather than relying on the outer document-level observer's single fire-and-forget timeout.data-hrefattribute (already captured inthis.lastHoveredLinkon themouseoverhandler) instead of round-tripping through the popover's rendered title text would sidestep this whole timing dependency, sincedata-hrefis available immediately on hover, before the popover even starts rendering.Environment: