{"record":{"id":"1716e5f9d332e787","repo":"slidevjs/slidev","slug":"timesplit-end-end-is-before-start-ts","errorCode":null,"errorMessage":"Timesplit end ${end} is before start ${ts}","messagePattern":"Timesplit end (.+?) is before start (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/parser/src/timesplit/timesplit.ts","lineNumber":34,"sourceCode":"\nexport function parseTimesplits(inputs: TimesplitInput[]): TimesplitOutput[] {\n  let ts = 0\n  const outputs: TimesplitOutput[] = []\n  let current: TimesplitOutput = {\n    timestampStart: ts,\n    timestampEnd: ts,\n    noStart: 0,\n    noEnd: 0,\n    title: '[start]',\n  }\n  outputs.push(current)\n  for (const input of inputs) {\n    const time = parseTimeString(input.timesplit)\n    const end = time.relative\n      ? ts + time.seconds\n      : time.seconds\n    if (end < ts) {\n      throw new Error(`Timesplit end ${end} is before start ${ts}`)\n    }\n    current.timestampEnd = end\n    current.noEnd = input.no\n    if (input.title) {\n      current.title = input.title\n    }\n    ts = end\n    current = {\n      timestampStart: end,\n      timestampEnd: end,\n      noStart: input.no,\n      noEnd: input.no,\n    }\n    outputs.push(current)\n  }\n  return outputs\n}\n","sourceCodeStart":16,"sourceCodeEnd":52,"githubUrl":"https://github.com/slidevjs/slidev/blob/0d798ace5828966d9f77f62094d5f7a971ad98f7/packages/parser/src/timesplit/timesplit.ts#L16-L52","documentation":"parseTimesplits walks each slide's timesplit value and tracks a running end timestamp. If an absolute (non-relative) timesplit resolves to a value less than the current running total, time would move backwards, so it throws.","triggerScenarios":"Slide N has an absolute timesplit earlier than slide N-1's end, e.g. slide 2 ends at 1:00 and slide 3 declares timesplit: 0:30.","commonSituations":"Mixing absolute timestamps with relative (+...) offsets incorrectly; reordering slides without updating timesplits; off-by-one when computing offsets.","solutions":["Use relative offsets (+30s, +1m) so values are added to the running total","Ensure absolute timestamps are strictly monotonically increasing","Recompute all timesplits after reordering slides"],"exampleFix":"// before\nslide 2: timesplit: 1:00\nslide 3: timesplit: 0:30\n// after\nslide 3: timesplit: 1:30","handlingStrategy":"validation","validationCode":"let running = 0\nfor (const input of inputs) {\n  const t = parseTimeString(input.timesplit)\n  const end = t.relative ? running + t.seconds : t.seconds\n  if (end < running) throw new Error(`Non-monotonic timesplit at slide ${input.no}`)\n  running = end\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Use relative (+...) timesplit offsets to avoid monotonicity mistakes","After reordering slides, recompute all absolute timesplits"],"tags":["timesplit","video","parser"],"backgroundTag":null,"analyzedSha":"0d798ace5828966d9f77f62094d5f7a971ad98f7","analyzedAt":"2026-08-12T17:10:56.221Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}