slidevjs/slidev · error · Error
Nothing to update: provide at least one of `content`, `note`
Error message
Nothing to update: provide at least one of `content`, `note`, or `frontmatter`.
What it means
Thrown by the slidev-update-slide MCP tool handler when all of content, note, and frontmatter are null/undefined. The tool is a partial-update primitive; a call that changes nothing is a programming error rather than a no-op, so it is rejected before any data is fetched or written.
Source
Thrown at packages/slidev/node/mcp/server.ts:160
})
},
)
server.registerTool(
'slidev-update-slide',
{
title: 'Update slide',
description: 'Update the content, speaker note, and/or frontmatter of a slide. Only the provided fields are changed. Pass an empty string to clear the content or note. In `frontmatter`, only the given keys are patched; pass `null` as a value to delete that key.',
inputSchema: z.object({
no: noSchema,
content: z.string().optional().describe('New Markdown content of the slide (without frontmatter and note)'),
note: z.string().optional().describe('New speaker note (Markdown, stored as a trailing HTML comment)'),
frontmatter: frontmatterSchema,
}),
},
async ({ no, content, note, frontmatter }) => {
if (content == null && note == null && frontmatter == null)
throw new Error('Nothing to update: provide at least one of `content`, `note`, or `frontmatter`.')
const data = await ctx.getData()
const { slide } = await applySlidePatch(data, no, { content, note, frontmatter })
return result(`Updated slide ${no} in ${slide.source.filepath}.`)
},
)
server.registerTool(
'slidev-insert-slide',
{
title: 'Insert slide',
description: 'Insert a new slide after an existing slide (into the same markdown file). To add a slide at the very end, pass the last slide number.',
inputSchema: z.object({
after: z.number().int().min(1).describe('Slide number (1-based) after which the new slide is inserted'),
content: z.string().describe('Markdown content of the new slide'),
frontmatter: frontmatterSchema,
note: z.string().optional().describe('Speaker note of the new slide'),
}),
},View on GitHub (pinned to 0d798ace58)
Solutions
- Include at least one of content, note, or frontmatter in the call.
- If the intent was to read the slide, use slidev-get-slide instead.
- Pass an empty string ('') to clear content/note - that is a real change and is accepted.
Example fix
// before: nothing to change
await tools['slidev-update-slide']({ no: 3 }) // throws
// after: provide at least one field
await tools['slidev-update-slide']({ no: 3, content: '# Hello' })
// or clear the note:
await tools['slidev-update-slide']({ no: 3, note: '' }) Defensive patterns
Strategy: validation
Validate before calling
function hasUpdateField(p: { content?: unknown; note?: unknown; frontmatter?: unknown }): boolean {
return p.content != null || p.note != null || p.frontmatter != null
}
// before calling slidev-update-slide:
if (!hasUpdateField({ content, note, frontmatter })) {
throw new Error('update-slide needs content, note, or frontmatter.')
} Type guard
function isNonEmptyPatch(p: unknown): p is { content?: string; note?: string; frontmatter?: Record<string, unknown> } {
if (!p || typeof p !== 'object') return false
const { content, note, frontmatter } = p as any
return content != null || note != null || frontmatter != null
} Try / catch
try {
await tools['slidev-update-slide']({ no, content, note, frontmatter })
} catch (e) {
if (e instanceof Error && e.message.startsWith('Nothing to update')) {
// route to a read instead
return await tools['slidev-get-slide']({ no })
}
throw e
} Prevention
- Construct the update payload conditionally and abort if no field is set.
- Use slidev-get-slide for reads; reserve update-slide for real changes.
- Pass '' (empty string) to clear content/note - it counts as a change.
- Validate the patch client-side before the MCP round-trip.
When it happens
Trigger: Calling slidev-update-slide with an input object missing all three optional fields, or explicitly setting each to null/undefined.
Common situations: An agent calls update-slide as a no-op probe; a client forwards an empty patch object; conditional logic that omits every field when no condition matched.
Related errors
- Specify exactly one of `before` or `after`.
- The `before`/`after` anchor must be a different slide than `
- Slide ${no} does not exist. The deck has ${data.slides.lengt
- Invalid YAML frontmatter: ${parsed.errors.map(e => e.message
- Invalid timestamp format
AI-assisted analysis of slidevjs/slidev@0d798ace58 (2026-08-12).
Data as JSON: /api/errors/7721f0cd898636bd.
Report an issue: GitHub.