slidevjs/slidev · critical · Error
[slidev] The length of stepRanges does not match the length
Error message
[slidev] The length of stepRanges does not match the length of steps, this is an internal error.
What it means
An internal invariant check in the `ShikiMagicMove` client component. `steps` is the decoded array of Shiki Magic-Move token steps (decompressed from the `stepsLz` base64 prop), and `ranges` is the normalized `stepRanges` prop. Both are emitted together by Slidev's markdown compiler for `{1|2|3}`-style animated code blocks, so their lengths must agree. A mismatch means the compiled payload is internally inconsistent and the click-mapping logic (which indexes `ranges.value[i]` against `steps`) would read out of bounds.
Source
Thrown at packages/client/builtin/ShikiMagicMove.vue:93
if (!currentStep || !currentStep.code)
return
copy(currentStep.code.trim())
}
// Normalized the ranges, to at least have one range
const ranges = computed(() => props.stepRanges.map(i => i.length ? i : ['all']))
onUnmounted(() => {
clicks?.unregister(id)
})
onMounted(() => {
if (!clicks)
return
if (ranges.value.length !== steps.length)
throw new Error('[slidev] The length of stepRanges does not match the length of steps, this is an internal error.')
const clickCounts = ranges.value.map(s => s.length).reduce((a, b) => a + b, 0)
const clickInfo = clicks.calculateSince(props.at, clickCounts - 1)
clicks.register(id, clickInfo)
let cancelTick: () => void = () => { }
watch(
() => clicks.current,
() => {
// Calculate the step and rangeStr based on the current click count
const clickCount = clickInfo ? clicks.current - clickInfo.start : CLICKS_MAX
let step = steps.length - 1
let currentClickSum = 0
let rangeStr = 'all'
for (let i = 0; i < ranges.value.length; i++) {
const current = ranges.value[i]
if (clickCount < currentClickSum + current.length - 1) {
step = iView on GitHub (pinned to 0d798ace58)
Solutions
- This is an internal error — file a Slidev bug with the offending Magic-Move code block and the @slidev package versions.
- Ensure all @slidev/* packages share one version (dedupe node_modules); version skew between the compiler and client is the leading cause.
- Clear Vite's transform cache (`node_modules/.vite`) and reload to discard a stale compiled module.
- If rendering ShikiMagicMove manually, pass `stepsLz` and `stepRanges` produced by the same compile step so their lengths match.
Defensive patterns
Strategy: validation
Validate before calling
// If you instantiate ShikiMagicMove.vue manually, assert the invariant first:
import lz from 'lz-string'
function magicMovePropsConsistent(stepsLz: string, stepRanges: string[][]): boolean {
const steps = JSON.parse(lz.decompressFromBase64(stepsLz)) as unknown[]
const ranges = stepRanges.map(i => i.length ? i : ['all'])
return ranges.length === steps.length
} Type guard
function stepsAndRangesMatch(stepsLz: string, stepRanges: string[][]): boolean {
const steps = JSON.parse(lz.decompressFromBase64(stepsLz)) as unknown[]
return stepRanges.map(i => i.length ? i : ['all']).length === steps.length
} Prevention
- Keep @slidev/client and @slidev/parser on the same version so the Magic-Move compiler and component agree on prop shape.
- Clear `node_modules/.vite` after upgrading Slidev to drop stale compiled Magic-Move modules.
- Never hand-edit the `stepsLz` / `stepRanges` props independently; they are a paired compiler output.
- If you render ShikiMagicMove outside Slidev, generate both props from the same compile pass.
When it happens
Trigger: Fires in `onMounted` when `ranges.value.length !== steps.length`. Because both props are generated by the same compiler pass for a single Magic-Move block, a mismatch implies corruption: a partially-overwritten/decompressed `stepsLz` whose decoded array length differs from `stepRanges`, a manual/programmatic instantiation of the component with mismatched props, or a version skew between the markdown compiler that emitted the props and the client component that validates them.
Common situations: Mixed @slidev/client and @slidev/parser versions where the Magic-Move fence compiler changed how it pairs `stepsLz` and `stepRanges`; a cached/stale transformed module in `node_modules/.vite` containing an old shape; hand-editing a compiled slide or rendering the component outside Slidev with inconsistent props.
Related errors
- [Slidev] Internal error: <script setup> block not found in s
- Package "${pkg}" not found in "${importer}"
- [slidev] Failed to load "${PWA_PACKAGE}", which is required
- No active slide project found.
- No content found for slide number ${input.slideNo} in entry:
AI-assisted analysis of slidevjs/slidev@0d798ace58 (2026-08-12).
Data as JSON: /api/errors/a2f8e0c144458063.
Report an issue: GitHub.