{"record":{"id":"7c0608230d3641f1","repo":"deepset-ai/haystack","slug":"pythoncodesplitter-only-works-with-text-documents-7c0608","errorCode":null,"errorMessage":"PythonCodeSplitter only works with text documents (str content).","messagePattern":"PythonCodeSplitter only works with text documents \\(str content\\)\\.","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"haystack/components/preprocessors/python_code_splitter.py","lineNumber":585,"sourceCode":"        Split each Python source ``Document`` into syntax-aware chunks.\n\n        :param documents: Documents whose ``content`` is Python source code. Each\n            document's ``meta`` is propagated onto its chunks.\n        :returns: ``{\"documents\": [...]}`` where each chunk's meta additionally carries\n            ``source_id``, ``split_id``, ``start_line``, ``end_line``, ``unit_kinds`` and\n            - where applicable - ``include_classes``, ``decorators``, ``docstrings``,\n            ``secondary_split``.\n        :raises ValueError: If any document's content is ``None``.\n        :raises TypeError: If any document's content is not a string.\n        :raises SyntaxError: If a document's content is not valid Python.\n        \"\"\"\n        for doc in documents:\n            if doc.content is None:\n                raise ValueError(\n                    f\"PythonCodeSplitter only works with text documents but content for document ID {doc.id} is None.\"\n                )\n            if not isinstance(doc.content, str):\n                raise TypeError(\"PythonCodeSplitter only works with text documents (str content).\")\n\n        final_docs: list[Document] = []\n        for doc in documents:\n            assert doc.content is not None  # narrowed by the loop above\n            if not doc.content.strip():\n                logger.warning(\"Document ID {doc_id} has empty content. Skipping this document.\", doc_id=doc.id)\n                continue\n\n            units = self._extract_units(doc.content)\n            if not units:\n                continue\n\n            chunks = self._merge_units(units)\n            split_id = 0\n            for chunk in chunks:\n                if len(chunk) == 1 and self._is_oversized(chunk[0]):\n                    for piece in self._secondary_split(chunk[0], doc):\n                        piece.meta[\"split_id\"] = split_id","sourceCodeStart":567,"sourceCodeEnd":603,"githubUrl":"https://github.com/deepset-ai/haystack/blob/e318778c9bf60a1963e3b5f451359655dd696c30/haystack/components/preprocessors/python_code_splitter.py#L567-L603","documentation":"PythonCodeSplitter.run() raises TypeError when a document's content is not a str. The splitter tokenizes Python source and can only handle string content; arbitrary objects (bytes, lists, dicts) are rejected explicitly rather than failing obscurely later.","triggerScenarios":"Passing documents whose content is bytes (e.g. raw file reads), a list of chunks, or any non-str object; constructing Document(content=<non-str>) manually and feeding it to run().","commonSituations":"Reading files in binary mode ('rb') upstream; custom components that store structured data in content; version changes after migrating from another splitter that accepted different types.","solutions":["Decode bytes before wrapping: Document(content=data.decode('utf-8')).","Ensure upstream components emit str content (check the converter used).","Add an isinstance check in a custom component before emitting documents."],"exampleFix":"// before\nDocument(content=open(path, 'rb').read())\n// after\nDocument(content=open(path, 'r', encoding='utf-8').read())","handlingStrategy":"type-guard","validationCode":"bad = [d.id for d in documents if not isinstance(d.content, str)]\nif bad:\n    raise TypeError(f'Non-str content in documents: {bad}')","typeGuard":"def is_text_document(doc) -> bool:\n    return isinstance(doc.content, str)\n\ndocuments = [d for d in documents if is_text_document(d)]","tryCatchPattern":"try:\n    result = splitter.run(documents=docs)\nexcept TypeError as e:\n    logger.error('Non-str document content: %s', e)\n    result = splitter.run(documents=[d for d in docs if isinstance(d.content, str)])","preventionTips":["Always open files in text mode with explicit encoding before creating Documents.","Enforce str content in custom components before emitting.","Type-annotate pipelines so mypy catches non-str content flows."],"tags":["python","haystack","typeerror","document-content"],"backgroundTag":"invalid-document-content","analyzedSha":"e318778c9bf60a1963e3b5f451359655dd696c30","analyzedAt":"2026-08-30T11:45:20.711Z","schemaVersion":2},"datasetVersion":"2026-08-30T13:17:10.514Z"}