{"record":{"id":"c6e431e53f31e71e","repo":"microsoft/VibeVoice","slug":"json-file-must-contain-a-list-of-speaker-entries","errorCode":null,"errorMessage":"JSON file must contain a list of speaker entries","messagePattern":"JSON file must contain a list of speaker entries","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"vibevoice/processor/vibevoice_processor.py","lineNumber":526,"sourceCode":"            \n        return result\n        \n    def _convert_json_to_script(self, json_file: str) -> str:\n        \"\"\"\n        Convert JSON format to script format.\n        Expected JSON format:\n        [\n            {\"speaker\": \"1\", \"text\": \"Hello everyone...\"},\n            {\"speaker\": \"2\", \"text\": \"Great to be here...\"}\n        ]\n        \"\"\"\n        import json\n        \n        with open(json_file, 'r', encoding='utf-8') as f:\n            data = json.load(f)\n        \n        if not isinstance(data, list):\n            raise ValueError(\"JSON file must contain a list of speaker entries\")\n        \n        script_lines = []\n        for item in data:\n            if not isinstance(item, dict):\n                logger.warning(f\"Skipping non-dict entry: {item}\")\n                continue\n                \n            speaker = item.get('speaker')\n            text = item.get('text')\n            \n            if speaker is None or text is None:\n                logger.warning(f\"Skipping entry missing speaker or text: {item}\")\n                continue\n            \n            # Ensure speaker ID is valid\n            try:\n                speaker_id = int(speaker)\n            except (ValueError, TypeError):","sourceCodeStart":508,"sourceCodeEnd":544,"githubUrl":"https://github.com/microsoft/VibeVoice/blob/94da20d98b2fa7688e9cbfaf7692ddb4954f7600/vibevoice/processor/vibevoice_processor.py#L508-L544","documentation":"When `text` points at a .json file, the processor expects a top-level JSON array of {'speaker': ..., 'text': ...} entries. If json.load succeeds but yields an object (dict), a string, a number, or null, this ValueError is raised — the file parsed fine but has the wrong shape.","triggerScenarios":"Passing a .json file whose root is a dict — e.g. {\"segments\": [...]} or a bare {'speaker': '1', 'text': 'hi'} entry instead of a list wrapping it; or a JSON-lines file (one object per line) which json.load reads as whatever the first scalar parses to.","commonSituations":"Datasets that wrap transcripts in a metadata object ({'utterances': [...]}); annotation tools exporting a single-session dict; users hand-editing the example format and dropping the outer brackets.","solutions":["Rewrite the JSON to a top-level list: [{\"speaker\": \"1\", \"text\": \"...\"}, {\"speaker\": \"2\", \"text\": \"...\"}].","If your file wraps entries under a key (e.g. 'segments'), extract that array into a new file or pass the inner list via a temp file.","Convert JSON-lines exports to a single JSON array before feeding them in."],"exampleFix":"// before: dialog.json\n{\"segments\": [{\"speaker\": \"1\", \"text\": \"Hi\"}]}\n\n// after: dialog.json\n[{\"speaker\": \"1\", \"text\": \"Hi\"}]","handlingStrategy":"validation","validationCode":"import json\ndata = json.load(open(path))\nif not isinstance(data, list):\n    for key in ('segments', 'utterances', 'data'):  # common wrappers\n        if isinstance(data, dict) and isinstance(data.get(key), list):\n            data = data[key]; break\n    else:\n        raise ValueError('transcript JSON root must be a list of speaker entries')","typeGuard":"def is_speaker_entry_list(data) -> bool:\n    return isinstance(data, list) and all(\n        isinstance(x, dict) and 'speaker' in x and 'text' in x for x in data)","tryCatchPattern":"try:\n    enc = processor(text=json_path)\nexcept ValueError as e:\n    if 'must contain a list' in str(e):\n        data = json.load(open(json_path))['segments']  # unwrap known container\n        json.dump(data, open(json_path, 'w'))\n        enc = processor(text=json_path)\n    else:\n        raise","preventionTips":["Validate the JSON root type right after json.load in your own loading code.","Standardize transcript exports on the flat [{'speaker','text'}] schema.","Watch for JSON-lines files; convert them to a single array first."],"tags":["json","script","file-format","validation"],"backgroundTag":null,"analyzedSha":"94da20d98b2fa7688e9cbfaf7692ddb4954f7600","analyzedAt":"2026-08-15T04:12:07.418Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}