slidevjs/slidev · error · Error
Specify exactly one of `before` or `after`.
Error message
Specify exactly one of `before` or `after`.
What it means
Thrown by moveSlide when (before == null) === (after == null), i.e. the caller supplied both before and after, or neither. The tool requires exactly one anchor so the insertion point is unambiguous.
Source
Thrown at packages/slidev/node/mcp/operations.ts:172
before?: number
/** Move the slide right after this rendered slide number */
after?: number
}
export interface MoveSlideResult {
moved: SlideInfo
anchor: SlideInfo
filepath: string
fileContent: string
}
/**
* Move a slide before or after another slide within the same markdown file.
*/
export async function moveSlide(data: LoadedSlidevData, options: MoveSlideOptions): Promise<MoveSlideResult> {
const { from, before, after } = options
if ((before == null) === (after == null))
throw new Error('Specify exactly one of `before` or `after`.')
const anchorNo = (before ?? after)!
if (anchorNo === from)
throw new Error('The `before`/`after` anchor must be a different slide than `from`.')
const slide = resolveSlide(data, from)
const anchor = resolveSlide(data, anchorNo)
if (slide.source.filepath !== anchor.source.filepath) {
throw new Error(
`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.`,
)
}
assertNotEntryHeadmatter(data, slide.source, 'move')
if (before != null)View on GitHub (pinned to 0d798ace58)
Solutions
- Provide exactly one of before (move to just before that slide) or after (move to just after that slide).
- If you only have a target position, compute one anchor and omit the other entirely (do not pass null).
Example fix
// before: ambiguous - both anchors
await tools['slidev-move-slide']({ from: 2, before: 5, after: 5 }) // throws
// after: exactly one anchor
await tools['slidev-move-slide']({ from: 2, before: 5 }) Defensive patterns
Strategy: validation
Validate before calling
function exactlyOneAnchor(opts: { before?: number; after?: number }): boolean {
return (opts.before != null) !== (opts.after != null)
}
// before moveSlide:
if (!exactlyOneAnchor({ before, after })) {
throw new Error('Pass exactly one of `before` or `after`.')
} Type guard
function hasSingleAnchor(o: unknown): o is { before?: number; after?: number } {
if (!o || typeof o !== 'object') return false
const { before, after } = o as any
return (before != null) !== (after != null)
} Try / catch
try {
await moveSlide(data, { from, before, after })
} catch (e) {
if (e instanceof Error && e.message === 'Specify exactly one of `before` or `after`.') {
// pick a sensible default anchor and retry, or prompt the caller
return { error: 'Ambiguous move: provide exactly one of before/after.' }
}
throw e
} Prevention
- In agent code, construct the move options object with exactly one anchor key.
- Omit the unused anchor entirely rather than passing null/undefined.
- Validate the XOR condition client-side before the MCP round-trip.
- Document the move intent (reorder forward vs backward) by choosing after vs before.
When it happens
Trigger: Calling slidev-move-slide (or moveSlide) with both before and after set, or with both omitted.
Common situations: An agent defaults both fields to undefined; a client serializes an empty object as {before: null, after: null}; misunderstanding that exactly one anchor is mandatory.
Related errors
- The `before`/`after` anchor must be a different slide than `
- Nothing to update: provide at least one of `content`, `note`
- Slide ${no} does not exist. The deck has ${data.slides.lengt
- Invalid YAML frontmatter: ${parsed.errors.map(e => e.message
- Cannot move a slide across markdown files: slide ${from} is
AI-assisted analysis of slidevjs/slidev@0d798ace58 (2026-08-12).
Data as JSON: /api/errors/528b4d5d130d30b2.
Report an issue: GitHub.