{"record":{"id":"21c3c7c2589162e4","repo":"slidevjs/slidev","slug":"slidev-vdrag-element-id-is-missing-markdown-s","errorCode":null,"errorMessage":"[Slidev] VDrag Element ${id} is missing markdown source","messagePattern":"\\[Slidev\\] VDrag Element (.+?) is missing markdown source","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/client/composables/useDragElements.ts","lineNumber":66,"sourceCode":"  return map[no] = (id, posStr, type, markdownSource) => {\n    if (!info.value)\n      return\n\n    if (type === 'frontmatter') {\n      const frontmatter = info.value.frontmatter\n      frontmatter.dragPos ||= {}\n      if (frontmatter.dragPos[id] === posStr)\n        return\n      frontmatter.dragPos[id] = posStr\n      newPatch = {\n        frontmatter: {\n          dragPos: frontmatter.dragPos,\n        },\n      }\n    }\n    else {\n      if (!markdownSource)\n        throw new Error(`[Slidev] VDrag Element ${id} is missing markdown source`)\n\n      const [startLine, endLine, idx] = markdownSource\n      const lines = info.value.content.split(RE_NEWLINE)\n\n      let section = lines.slice(startLine, endLine).join('\\n')\n      let replaced = false\n\n      section = type === 'prop'\n      // eslint-disable-next-line regexp/no-super-linear-backtracking\n        ? section.replace(/<(v-?drag-?\\w*)(.*?)(\\/)?>/gi, (full, tag, attrs, selfClose = '', index) => {\n            if (index === idx) {\n              replaced = true\n              const posMatch = attrs.match(RE_POS_ATTR)\n              if (!posMatch)\n                return `<${tag}${ensureSuffix(' ', attrs)}pos=\"${posStr}\"${selfClose}>`\n              const start = posMatch.index\n              const end = start + posMatch[0].length\n              return `<${tag}${attrs.slice(0, start)}pos=\"${posStr}\"${attrs.slice(end)}${selfClose}>`","sourceCodeStart":48,"sourceCodeEnd":84,"githubUrl":"https://github.com/slidevjs/slidev/blob/0d798ace5828966d9f77f62094d5f7a971ad98f7/packages/client/composables/useDragElements.ts#L48-L84","documentation":"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.","triggerScenarios":"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.","commonSituations":"Dynamically rendered v-drag elements, custom components wrapping v-drag without forwarding markdownSource, or HMR losing the source range after edits.","solutions":["Add an explicit id=\"...\" prop so the element stores position in frontmatter dragPos instead of inline markdown","Ensure the v-drag element is authored directly in slides.md so its source range is captured","Forward the markdownSource argument through any custom wrapper component"],"exampleFix":"// before\n<v-drag pos=\"10,20,100,50\" />\n// after\n<v-drag id=\"card1\" />","handlingStrategy":"validation","validationCode":"if (type !== 'frontmatter' && !markdownSource) {\n  // fall back to frontmatter storage with a generated/known id\n  type = 'frontmatter'\n}","typeGuard":null,"tryCatchPattern":"try {\n  updater(id, posStr, type, markdownSource)\n} catch (e) {\n  if (/missing markdown source/.test(String(e))) {\n    // retry with frontmatter storage\n    updater(id, posStr, 'frontmatter', undefined)\n  } else throw e\n}","preventionTips":["Prefer id-based v-drag elements so positions live in frontmatter","Forward markdownSource through any custom wrapper around v-drag"],"tags":["v-drag","markdown","frontmatter"],"backgroundTag":null,"analyzedSha":"0d798ace5828966d9f77f62094d5f7a971ad98f7","analyzedAt":"2026-08-12T17:10:56.221Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}