babysor/MockingBird · error · ValueError

Invalid SRT timestamp: {value}

Error message

Invalid SRT timestamp: {value}

What it means

ValueError raised by parse_timestamp_ms when an SRT timestamp string does not match the expected HH:MM:SS,mmm pattern (e.g. 00:01:02,345). The regex TIMESTAMP_RE must match before groups are extracted, so malformed timestamps abort parsing.

Source

Thrown at skills/speak/scripts/render_timeline.py:61

@dataclass
class Cue:
    index: int
    start_ms: int
    end_ms: int
    text: str

    @property
    def duration_ms(self) -> int:
        return max(1, self.end_ms - self.start_ms)


# ── SRT parsing ──────────────────────────────────────────────────────


def parse_timestamp_ms(value: str) -> int:
    match = TIMESTAMP_RE.match(value.strip())
    if not match:
        raise ValueError(f"Invalid SRT timestamp: {value}")
    hh, mm, ss, ms = map(int, match.groups())
    return ((hh * 60 + mm) * 60 + ss) * 1000 + ms


def parse_srt(path: Path) -> List[Cue]:
    content = path.read_text(encoding="utf-8", errors="replace")
    blocks = re.split(r"\n\s*\n", content.strip())
    cues: List[Cue] = []
    for block in blocks:
        lines = [ln.rstrip() for ln in block.splitlines() if ln.strip()]
        if len(lines) < 3:
            continue
        try:
            idx = int(lines[0])
        except ValueError:
            continue
        if "-->" not in lines[1]:
            continue

View on GitHub (pinned to 28dc5e14f1)

Solutions

  1. Normalize timestamps: replace '.' with ',' in the ms field before parsing
  2. Fix the offending cue line shown in the message
  3. Re-export the subtitle from the authoring tool with SRT-standard formatting

Example fix

# before
start_ms = parse_timestamp_ms(start_raw)
# after
start_ms = parse_timestamp_ms(start_raw.strip().replace('.', ',') if start_raw.count(':') == 2 else start_raw)
Defensive patterns

Strategy: validation

Validate before calling

import re
TIMESTAMP = re.compile(r'^\d{2,}:\d{2}:\d{2}[,.]\d{3}$')
def is_valid_ts(v: str) -> bool:
    return bool(TIMESTAMP.match(v.strip()))

Type guard

def is_valid_timestamp(value: str) -> bool:
    return bool(re.match(r'^\d{2,}:\d{2}:\d{2},\d{3}$', value.strip()))

Try / catch

try:
    ms = parse_timestamp_ms(raw)
except ValueError:
    ms = parse_timestamp_ms(raw.replace('.', ','))

Prevention

When it happens

Trigger: Timestamps using '.' instead of ',' for milliseconds, missing components (MM:SS), extra spaces, or lines corrupted by encoding issues; also applies to end timestamps in cue ranges.

Common situations: SRT files edited by tools that emit period decimal separators, hand-edited files, files converted from VTT without normalization, or read with the wrong encoding.

Related errors


AI-assisted analysis of babysor/MockingBird@28dc5e14f1 (2026-08-27). Data as JSON: /api/errors/f2f82a3c3cda2ef3. Report an issue: GitHub.