slidevjs/slidev · error · Error

Markdown file not loaded: ${source.filepath}

Error message

Markdown file not loaded: ${source.filepath}

What it means

Thrown by the internal getMarkdown(data, source) helper when data.markdownFiles[source.filepath] is undefined. It signals that the markdown file backing a slide's source was never loaded into the LoadedSlidevData.markdownFiles map, so the operation cannot read or save it.

Source

Thrown at packages/slidev/node/mcp/operations.ts:21

import * as parser from '@slidev/parser/fs'
import YAML from 'yaml'
import { updateFrontmatterPatch } from '../utils'

/**
 * Resolve a rendered slide (1-based, as displayed in the presentation) or
 * throw a descriptive error.
 */
export function resolveSlide(data: LoadedSlidevData, no: number): SlideInfo {
  const slide = data.slides[no - 1]
  if (!slide)
    throw new Error(`Slide ${no} does not exist. The deck has ${data.slides.length} slides (1-${data.slides.length}).`)
  return slide
}

function getMarkdown(data: LoadedSlidevData, source: SourceSlideInfo) {
  const md = data.markdownFiles[source.filepath]
  if (!md)
    throw new Error(`Markdown file not loaded: ${source.filepath}`)
  return md
}

function assertNotEntryHeadmatter(data: LoadedSlidevData, source: SourceSlideInfo, action: string) {
  if (source.filepath === data.entry.filepath && data.entry.slides.indexOf(source) === 0) {
    throw new Error(
      `Cannot ${action} the first slide of the entry file: its frontmatter is the deck headmatter (global configuration). `
      + `Edit its content with the update tool instead, or operate on the following slides.`,
    )
  }
}

export interface SlidePatchResult {
  slide: SlideInfo
  fileContent: string
}

/**

View on GitHub (pinned to 0d798ace58)

Solutions

  1. Re-fetch fresh data with ctx.getData() immediately before the operation rather than reusing a cached snapshot.
  2. Confirm the filepath exists in Object.keys(data.markdownFiles) via slidev-get-info before editing.
  3. If a referenced file was deleted, restore it or remove the offending src: import from the entry, then reload.

Example fix

// before: reusing stale data across an external file change
const data = await ctx.getData()
// ... external process deletes the imported file ...
await applySlidePatch(data, no, { content: 'x' }) // throws: file not loaded

// after: always re-acquire data per operation
const data = await ctx.getData()
await applySlidePatch(data, no, { content: 'x' })
Defensive patterns

Strategy: validation

Validate before calling

function isMarkdownLoaded(data: LoadedSlidevData, filepath: string): boolean {
  return Object.prototype.hasOwnProperty.call(data.markdownFiles, filepath)
}

// before operating on a slide source:
const data = await ctx.getData()
if (!isMarkdownLoaded(data, slide.source.filepath)) {
  data = await ctx.getData() // refresh once
  if (!isMarkdownLoaded(data, slide.source.filepath)) return
}

Type guard

function markdownFileAvailable(data: LoadedSlidevData, filepath: string): boolean {
  return !!data.markdownFiles[filepath]
}

Try / catch

try {
  return getMarkdown(data, source)
} catch (e) {
  if (e instanceof Error && e.message.startsWith('Markdown file not loaded')) {
    // refresh data and retry once
    data = await ctx.getData()
    return getMarkdown(data, source)
  }
  throw e
}

Prevention

When it happens

Trigger: Calling applySlidePatch / removeSlide / moveSlide / insertSlide for a slide whose source.filepath is not a key in data.markdownFiles. This typically follows a stale ctx.getData() snapshot taken before a file was added/removed/renamed, or a deck whose entry was reloaded but partial-import state was not.

Common situations: Concurrent edits to the entry file's src: imports while the MCP tool runs; a slide imported from a file that was since deleted; an MCP client caching data across HMR reloads without re-calling getData().

Related errors


AI-assisted analysis of slidevjs/slidev@0d798ace58 (2026-08-12). Data as JSON: /api/errors/74bea1db58d93795. Report an issue: GitHub.