microsoft/VibeVoice · error · ValueError

No valid speaker lines found in script

Error message

No valid speaker lines found in script

What it means

The internal script format requires every dialogue line to match '^Speaker <digits>: <text>' (case-insensitive). _parse_script scans the script and keeps only matched lines; if none match — every line fell into the 'Could not parse line' warning branch — this ValueError is raised. This guards against downstream index errors on empty speaker lists.

Source

Thrown at vibevoice/processor/vibevoice_processor.py:619

                
        # First pass: parse all lines and collect speaker IDs
        for line in lines:
            if not line.strip():
                continue
                
            # Use regex to handle edge cases like multiple colons
            match = re.match(r'^Speaker\s+(\d+)\s*:\s*(.*)$', line.strip(), re.IGNORECASE)
            
            if match:
                speaker_id = int(match.group(1))
                text = ' ' + match.group(2).strip()
                parsed_lines.append((speaker_id, text))
                speaker_ids.append(speaker_id)
            else:
                logger.warning(f"Could not parse line: '{line}'")
        
        if not parsed_lines:
            raise ValueError("No valid speaker lines found in script")
        
        # Check if we need to normalize speaker IDs (only if all are > 0)
        min_speaker_id = min(speaker_ids)
        if min_speaker_id > 0:
            # Normalize to start from 0
            normalized_lines = []
            for speaker_id, text in parsed_lines:
                normalized_lines.append((speaker_id - 1, text))
            return normalized_lines
        else:
            # Keep original IDs
            return parsed_lines

    def _merge_inputs(self, text_inputs: BatchEncoding, audio_inputs: Dict) -> BatchEncoding:
        """Merge text and audio inputs into a single BatchEncoding."""
        # Start with text inputs
        merged = BatchEncoding(text_inputs)
        

View on GitHub (pinned to 94da20d98b)

Solutions

  1. Format the input as 'Speaker 1: <text>' lines, one utterance per line (any integer speaker ids work).
  2. For single-speaker plain text, wrap it programmatically: '\n'.join(f'Speaker 1: {line}' for line in text.splitlines() if line.strip()).
  3. Check preceding logger.warning lines to see exactly which lines failed to parse.

Example fix

# before
processor(text='Alice: hello there')

# after
processor(text='Speaker 1: hello there')
Defensive patterns

Strategy: validation

Validate before calling

import re
SPEAKER_RE = re.compile(r'^Speaker\s+\d+\s*:', re.IGNORECASE)
if not any(SPEAKER_RE.match(l) for l in script.splitlines() if l.strip()):
    script = '\n'.join(f'Speaker 1: {l}' for l in script.splitlines() if l.strip())

Type guard

def has_speaker_lines(script: str) -> bool:
    import re
    return any(re.match(r'^Speaker\s+\d+\s*:', l.strip(), re.I)
               for l in script.splitlines() if l.strip())

Try / catch

try:
    enc = processor(text=script)
except ValueError as e:
    if 'No valid speaker lines' in str(e):
        wrapped = '\n'.join(f'Speaker 1: {l}' for l in script.splitlines() if l.strip())
        enc = processor(text=wrapped)
    else:
        raise

Prevention

When it happens

Trigger: Passing a script string in a different dialogue format: 'Alice: hi', '[1]: hi', '1: hi' (missing the literal word 'Speaker'), or a raw paragraph with no speaker prefixes at all.

Common situations: Users passing free-form narration text expecting single-speaker TTS; scripts exported with speaker labels like 'S1:' or character names; localizing the word 'Speaker' into another language.

Related errors


AI-assisted analysis of microsoft/VibeVoice@94da20d98b (2026-08-15). Data as JSON: /api/errors/34ee02f837c8c0fb. Report an issue: GitHub.