{"record":{"id":"c0b32fb92264c191","repo":"fishaudio/fish-speech","slug":"unsupported-part-type-part-type","errorCode":null,"errorMessage":"Unsupported part type: {part['type']}","messagePattern":"Unsupported part type: (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"fish_speech/content_sequence.py","lineNumber":105,"sourceCode":"        self: \"ContentSequence\",\n        parts: list[BasePart | dict] | None = None,\n        modality: Literal[\"text\", \"voice\", \"interleave\"] | None = None,\n        metadata: dict | None = None,\n    ):\n        self.modality = modality\n        self.metadata = metadata or {}\n\n        fixed_parts = []\n        for part in parts or []:\n            if isinstance(part, dict):\n                if part[\"type\"] == \"vq\":\n                    part = VQPart(**part)\n                elif part[\"type\"] == \"audio\":\n                    part = AudioPart(**part)\n                elif part[\"type\"] == \"text\":\n                    part = TextPart(**part)\n                else:\n                    raise ValueError(f\"Unsupported part type: {part['type']}\")\n            fixed_parts.append(part)\n\n        self.parts = fixed_parts\n\n        # If modality is specified, add it at the beginning if it's not already there\n        if self.modality and not (\n            len(self.parts) > 0\n            and isinstance(self.parts[0], dict) is False\n            and isinstance(self.parts[0], TextPart)\n            and self.parts[0].text is not None\n            and self.parts[0].text.startswith(MODALITY_TOKENS[self.modality])\n        ):\n            modality_token = MODALITY_TOKENS[self.modality]\n            self.parts.insert(0, TextPart(text=modality_token))\n\n    def append(\n        self: \"ContentSequence\",\n        part_or_parts: Union[BasePart, List[BasePart]],","sourceCodeStart":87,"sourceCodeEnd":123,"githubUrl":"https://github.com/fishaudio/fish-speech/blob/befe4001745417f8c42131739d862b8a6fdbd15a/fish_speech/content_sequence.py#L87-L123","documentation":"When a ContentSequence is constructed, any part given as a plain dict is converted to the appropriate part dataclass (VQPart, AudioPart, TextPart) based on its \"type\" key. If the dict's type is not one of these known types, the part cannot be mapped and a ValueError is raised.","triggerScenarios":"Passing a dict part like {\"type\": \"image\", ...} or {\"type\": \"vq_codes\"} (misspelled) into ContentSequence(parts=[...]); any type key outside {vq, audio, text} (and whatever earlier branches accept).","commonSituations":"Loading serialized sequences from JSON where the schema changed between versions, typos in the type field, or hand-authored part dicts using wrong type names.","solutions":["Check the accepted part types in content_sequence.py and fix the dict's type key (e.g. \"vq\", \"audio\", \"text\")","If loading old serialized data, migrate/normalize the type field before constructing ContentSequence","Pass part dataclass instances (VQPart/AudioPart/TextPart) instead of dicts to get type checking earlier"],"exampleFix":"# before\nseq = ContentSequence(parts=[{\"type\": \"image\", \"path\": \"x.png\"}])\n\n# after\nseq = ContentSequence(parts=[{\"type\": \"text\", \"text\": \"hello\"}])","handlingStrategy":"validation","validationCode":"ALLOWED_PART_TYPES = {\"vq\", \"audio\", \"text\"}\n\nparts = [p for p in raw_parts if p.get(\"type\") in ALLOWED_PART_TYPES] if all(isinstance(p, dict) for p in raw_parts) else raw_parts\nseq = ContentSequence(parts=parts)","typeGuard":"def is_supported_part_dict(p) -> bool:\n    return isinstance(p, dict) and p.get(\"type\") in {\"vq\", \"audio\", \"text\"}","tryCatchPattern":"try:\n    seq = ContentSequence(parts=raw_parts)\nexcept ValueError as e:\n    if \"Unsupported part type\" in str(e):\n        # filter or migrate bad dicts, then retry\n        ...\n    raise","preventionTips":["Validate serialized parts against a schema before loading","Pass dataclass instances instead of dicts where possible"],"tags":["validation","serialization","content-sequence","python"],"backgroundTag":"unknown-discriminator-value","analyzedSha":"befe4001745417f8c42131739d862b8a6fdbd15a","analyzedAt":"2026-08-27T21:31:45.703Z","schemaVersion":2},"datasetVersion":"2026-08-28T00:17:15.603Z"}