slidevjs/slidev · error · Error

[Slidev] VDrag Element ${id} is missing markdown source

Error message

[Slidev] VDrag Element ${id} is missing markdown source

What it means

Thrown when the drag-element updater is asked to persist a position back to the markdown source (data source 'prop' or 'directive') but no markdownSource tuple [startLine, endLine, idx] was supplied. Without it Slidev cannot locate the element's text to rewrite.

Source

Thrown at packages/client/composables/useDragElements.ts:66

  return map[no] = (id, posStr, type, markdownSource) => {
    if (!info.value)
      return

    if (type === 'frontmatter') {
      const frontmatter = info.value.frontmatter
      frontmatter.dragPos ||= {}
      if (frontmatter.dragPos[id] === posStr)
        return
      frontmatter.dragPos[id] = posStr
      newPatch = {
        frontmatter: {
          dragPos: frontmatter.dragPos,
        },
      }
    }
    else {
      if (!markdownSource)
        throw new Error(`[Slidev] VDrag Element ${id} is missing markdown source`)

      const [startLine, endLine, idx] = markdownSource
      const lines = info.value.content.split(RE_NEWLINE)

      let section = lines.slice(startLine, endLine).join('\n')
      let replaced = false

      section = type === 'prop'
      // eslint-disable-next-line regexp/no-super-linear-backtracking
        ? section.replace(/<(v-?drag-?\w*)(.*?)(\/)?>/gi, (full, tag, attrs, selfClose = '', index) => {
            if (index === idx) {
              replaced = true
              const posMatch = attrs.match(RE_POS_ATTR)
              if (!posMatch)
                return `<${tag}${ensureSuffix(' ', attrs)}pos="${posStr}"${selfClose}>`
              const start = posMatch.index
              const end = start + posMatch[0].length
              return `<${tag}${attrs.slice(0, start)}pos="${posStr}"${attrs.slice(end)}${selfClose}>`

View on GitHub (pinned to 0d798ace58)

Solutions

  1. Add an explicit id="..." prop so the element stores position in frontmatter dragPos instead of inline markdown
  2. Ensure the v-drag element is authored directly in slides.md so its source range is captured
  3. Forward the markdownSource argument through any custom wrapper component

Example fix

// before
<v-drag pos="10,20,100,50" />
// after
<v-drag id="card1" />
Defensive patterns

Strategy: validation

Validate before calling

if (type !== 'frontmatter' && !markdownSource) {
  // fall back to frontmatter storage with a generated/known id
  type = 'frontmatter'
}

Try / catch

try {
  updater(id, posStr, type, markdownSource)
} catch (e) {
  if (/missing markdown source/.test(String(e))) {
    // retry with frontmatter storage
    updater(id, posStr, 'frontmatter', undefined)
  } else throw e
}

Prevention

When it happens

Trigger: Calling useDragElementsUpdater's returned callback with type !== 'frontmatter' and a falsy markdownSource argument, e.g. a v-drag directive rendered outside the markdown pipeline or with its source range stripped.

Common situations: Dynamically rendered v-drag elements, custom components wrapping v-drag without forwarding markdownSource, or HMR losing the source range after edits.

Related errors


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