{"record":{"id":"a1b3e1b0c496c602","repo":"slidevjs/slidev","slug":"cannot-move-a-slide-across-markdown-files-slide","errorCode":null,"errorMessage":"Cannot move a slide across markdown files: slide ${from} is in \"${slide.source.filepath}\" but slide ${anchorNo} is in \"${anchor.source.filepath}\" (imported with `src:`). Move it within its own file, or edit the `src:` imports in the entry file manually.","messagePattern":"Cannot move a slide across markdown files: slide (.+?) is in \"(.+?)\" but slide (.+?) is in \"(.+?)\" \\(imported with `src:`\\)\\. Move it within its own file, or edit the `src:` imports in the entry file manually\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/slidev/node/mcp/operations.ts","lineNumber":182,"sourceCode":"}\n\n/**\n * Move a slide before or after another slide within the same markdown file.\n */\nexport async function moveSlide(data: LoadedSlidevData, options: MoveSlideOptions): Promise<MoveSlideResult> {\n  const { from, before, after } = options\n  if ((before == null) === (after == null))\n    throw new Error('Specify exactly one of `before` or `after`.')\n\n  const anchorNo = (before ?? after)!\n  if (anchorNo === from)\n    throw new Error('The `before`/`after` anchor must be a different slide than `from`.')\n\n  const slide = resolveSlide(data, from)\n  const anchor = resolveSlide(data, anchorNo)\n\n  if (slide.source.filepath !== anchor.source.filepath) {\n    throw new Error(\n      `Cannot move a slide across markdown files: slide ${from} is in \"${slide.source.filepath}\" `\n      + `but slide ${anchorNo} is in \"${anchor.source.filepath}\" (imported with \\`src:\\`). `\n      + `Move it within its own file, or edit the \\`src:\\` imports in the entry file manually.`,\n    )\n  }\n\n  assertNotEntryHeadmatter(data, slide.source, 'move')\n  if (before != null)\n    assertNotEntryHeadmatter(data, anchor.source, 'insert a slide before')\n\n  const md = getMarkdown(data, slide.source)\n  const fromIdx = md.slides.indexOf(slide.source)\n  if (fromIdx < 0)\n    throw new Error(`Slide ${from} is out of sync with its source file. Try again.`)\n  md.slides.splice(fromIdx, 1)\n  const anchorIdx = md.slides.indexOf(anchor.source)\n  if (anchorIdx < 0)\n    throw new Error(`Slide ${anchorNo} is out of sync with its source file. Try again.`)","sourceCodeStart":164,"sourceCodeEnd":200,"githubUrl":"https://github.com/slidevjs/slidev/blob/0d798ace5828966d9f77f62094d5f7a971ad98f7/packages/slidev/node/mcp/operations.ts#L164-L200","documentation":"Thrown by moveSlide when slide.source.filepath !== anchor.source.filepath. moveSlide only reorders within a single markdown file; slides imported via the src: directive live in separate files and cannot be moved across the import boundary by this tool.","triggerScenarios":"Calling slidev-move-slide where from and before/after resolve to slides whose source.filepath differ - one or both come from a file pulled in through src: imports.","commonSituations":"A modular deck splits slides into multiple .md files via src:; an agent addresses rendered numbers without checking they share a source file; trying to move an imported slide into the entry file (or vice versa).","solutions":["Move the slide within its own source file (re-fetch the data, find its file, and choose an anchor in the same file).","To relocate across files, edit the src: imports in the entry markdown by hand (reorder/repoint the import lines) and reload.","Run slidev-list-slides and check the 'file' field per slide to confirm both share a filepath before calling moveSlide."],"exampleFix":"// before: from in slides.md, anchor in chapter1.md (imported via src:)\nawait tools['slidev-move-slide']({ from: 2, before: 6 }) // throws\n\n// after: pick an anchor in the same file as slide 2\n// (list-slides shows slide 2 and slide 4 both in ./slides.md)\nawait tools['slidev-move-slide']({ from: 2, before: 4 })","handlingStrategy":"validation","validationCode":"function sameFile(a: SourceSlideInfo, b: SourceSlideInfo): boolean {\n  return a.filepath === b.filepath\n}\n\n// before moveSlide:\nconst data = await ctx.getData()\nconst slide = resolveSlide(data, from)\nconst anchor = resolveSlide(data, before ?? after!)\nif (!sameFile(slide.source, anchor.source)) {\n  throw new Error('Use update on src: imports or move within the same file.')\n}","typeGuard":"function slidesShareFile(a: SlideInfo, b: SlideInfo): boolean {\n  return a.source.filepath === b.source.filepath\n}","tryCatchPattern":"try {\n  await moveSlide(data, { from, before, after })\n} catch (e) {\n  if (e instanceof Error && /Cannot move a slide across markdown files/.test(e.message)) {\n    // fall back: edit the src: import order in the entry markdown\n    return { error: 'Cross-file move blocked; reorder src: imports manually.' }\n  }\n  throw e\n}","preventionTips":["Use slidev-list-slides and compare the 'file' field before moving.","Keep slides you intend to reorder together in one markdown file.","For modular decks, reorder src: import lines in the entry to change inter-file order.","Teach agents that move is intra-file only."],"tags":["mcp","move","src-imports","multi-file"],"backgroundTag":null,"analyzedSha":"0d798ace5828966d9f77f62094d5f7a971ad98f7","analyzedAt":"2026-08-12T17:10:56.221Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}