slidevjs/slidev · error · Error
Slide ${no} does not exist. The deck has ${data.slides.lengt
Error message
Slide ${no} does not exist. The deck has ${data.slides.length} slides (1-${data.slides.length}). What it means
Thrown by resolveSlide(data, no) when data.slides[no - 1] is falsy. Slides are addressed 1-based (matching presentation slide numbers); the error message echoes the valid 1..N range. Every MCP operation tool routes its slide-number argument through this guard.
Source
Thrown at packages/slidev/node/mcp/operations.ts:14
import type { LoadedSlidevData } from '@slidev/parser/fs'
import type { SlideInfo, SlidePatch, SourceSlideInfo } from '@slidev/types'
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.`,
)
}
}View on GitHub (pinned to 0d798ace58)
Solutions
- Call slidev-list-slides again to refresh slide numbers after any insert/remove/move, then retry with a valid number.
- Pass a number in the range 1..totalSlides reported by slidev-get-info.
- If the caller holds stale state, re-fetch via ctx.getData() before indexing.
Example fix
// before: stale number after a remove
await tools['slidev-remove-slide']({ no: 3 })
await tools['slidev-get-slide']({ no: 5 }) // deck now shorter -> throws
// after: refresh, then index by the new layout
const slides = await tools['slidev-list-slides']({})
const last = slides.at(-1).no
await tools['slidev-get-slide']({ no: last }) Defensive patterns
Strategy: validation
Validate before calling
function assertSlideNo(data: { slides: unknown[] }, no: number): void {
if (!Number.isInteger(no) || no < 1 || no > data.slides.length) {
throw new RangeError(`Slide no must be 1..${data.slides.length}, got ${no}`)
}
}
// before any tool call:
const data = await ctx.getData()
assertSlideNo(data, requestedNo) Type guard
function isValidSlideNo(no: unknown, total: number): no is number {
return typeof no === 'number'
&& Number.isInteger(no)
&& no >= 1
&& no <= total
} Try / catch
try {
const slide = resolveSlide(data, no)
} catch (e) {
if (e instanceof Error && /does not exist\./.test(e.message)) {
// re-list and surface the valid range to the caller/agent
const total = data.slides.length
return { error: `invalid slide number; valid range is 1-${total}` }
}
throw e
} Prevention
- After any insert/remove/move, call slidev-list-slides before reusing slide numbers.
- Treat slide numbers as ephemeral; never cache them across mutations.
- Always read totalSlides from slidev-get-info before constructing requests.
- Prefer addressing slides by title or content match, then resolve to a number, in agent flows.
When it happens
Trigger: Calling any slide-scoped MCP tool (slidev-get-slide, slidev-update-slide, slidev-remove-slide, slidev-move-slide, slidev-goto-slide) with a number greater than data.slides.length, less than 1, or a number that became stale after a prior insert/remove/move shifted the deck.
Common situations: An agent edits the deck (insert/remove) and reuses an old slide number without re-listing; user passes a 0-based index by mistake; hidden/disabled slides shrink the visible count vs. what the caller assumed.
Related errors
- Invalid YAML frontmatter: ${parsed.errors.map(e => e.message
- Specify exactly one of `before` or `after`.
- The `before`/`after` anchor must be a different slide than `
- Nothing to update: provide at least one of `content`, `note`
- Invalid timestamp format
AI-assisted analysis of slidevjs/slidev@0d798ace58 (2026-08-12).
Data as JSON: /api/errors/694d89378c0b5a34.
Report an issue: GitHub.