{"record":{"id":"a1bb5014b8c6248d","repo":"apache/beam","slug":"text-splitter-must-be-a-langchain-textsplitter","errorCode":null,"errorMessage":"text_splitter must be a LangChain TextSplitter","messagePattern":"text_splitter must be a LangChain TextSplitter","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"sdks/python/apache_beam/ml/rag/chunking/langchain.py","lineNumber":85,"sourceCode":"            | beam.Create([{'text': 'long document...', 'source': 'doc.txt'}])\n            | MLTransform(...).with_transform(chunker))\n      ```\n\n    Args:\n      text_splitter: A LangChain TextSplitter instance that defines how\n        documents are split into chunks.\n      metadata_fields: List of field names to copy from input documents to\n        chunk metadata. These fields will be preserved in each chunk created\n        from the document.\n      chunk_id_fn: Optional function that take a Chunk and return str to\n        generate chunk IDs. If not provided, random UUIDs will be used.\n    \"\"\"\n    if not TextSplitter:\n      raise ImportError(\n          \"langchain is required to use LangChainChunker\"\n          \"Please install it with using `pip install langchain`.\")\n    if not isinstance(text_splitter, TextSplitter):\n      raise TypeError(\"text_splitter must be a LangChain TextSplitter\")\n    if not document_field:\n      raise ValueError(\"document_field cannot be empty\")\n    super().__init__(chunk_id_fn)\n    self.text_splitter = text_splitter\n    self.document_field = document_field\n    self.metadata_fields = metadata_fields\n\n  def get_splitter_transform(\n      self\n  ) -> beam.PTransform[beam.PCollection[dict[str, Any]],\n                       beam.PCollection[Chunk]]:\n    return \"Langchain text split\" >> beam.ParDo(\n        _LangChainTextSplitter(\n            text_splitter=self.text_splitter,\n            document_field=self.document_field,\n            metadata_fields=self.metadata_fields))\n\n","sourceCodeStart":67,"sourceCodeEnd":103,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/python/apache_beam/ml/rag/chunking/langchain.py#L67-L103","documentation":"LangChainChunker.__init__ raises this TypeError when the text_splitter argument is not an instance of langchain's TextSplitter class. The constructor validates the type up front so misconfiguration surfaces at pipeline construction time instead of failing inside workers mid-run. Only LangChain TextSplitter subclasses (e.g. RecursiveCharacterTextSplitter, CharacterTextSplitter) are accepted.","triggerScenarios":"Passing a non-TextSplitter object as text_splitter, e.g. a SemanticChunker, a plain function, a LangChain text_splitter from a different module namespace (langchain_text_splitters vs langchain.text_splitter in versions where the class identity differs), None when langchain is installed but the arg was omitted, or a custom splitter not subclassing TextSplitter.","commonSituations":"Using a splitter class imported from a different package than the one LangChainChunker imported (duplicate/mismatched langchain installs); passing a SentenceTransformerEmbeddings or other langchain object by mistake; custom splitter classes duck-typing the interface without inheriting TextSplitter.","solutions":["Pass a genuine LangChain TextSplitter instance, e.g. RecursiveCharacterTextSplitter(chunk_size=..., chunk_overlap=...).","If you have a custom splitter, make it subclass langchain TextSplitter (implement split_text).","Verify imports come from the same installed langchain/text-splitters package (pip show langchain; avoid multiple copies)."],"exampleFix":"// before\nchunker = LangChainChunker(text_splitter=my_custom_split_fn, document_field='contents')\n\n// after\nfrom langchain_text_splitters import RecursiveCharacterTextSplitter\nchunker = LangChainChunker(\n    text_splitter=RecursiveCharacterTextSplitter(chunk_size=1000, chunk_overlap=100),\n    document_field='contents')","handlingStrategy":"type-guard","validationCode":"def validate_splitter(splitter) -> bool:\n    from langchain_text_splitters import TextSplitter\n    if not isinstance(splitter, TextSplitter):\n        raise TypeError('text_splitter must be a LangChain TextSplitter')\n    return True","typeGuard":"def is_text_splitter(obj) -> bool:\n    try:\n        from langchain_text_splitters import TextSplitter\n        return isinstance(obj, TextSplitter)\n    except ImportError:\n        return False","tryCatchPattern":"try:\n    chunker = LangChainChunker(text_splitter=splitter, document_field='contents')\nexcept TypeError as e:\n    logging.error('Bad splitter: %s (type=%s)', e, type(splitter).__name__)\n    raise","preventionTips":["Import splitters from the same langchain/text-splitters package your code uses everywhere.","Add isinstance assertions in pipeline-construction unit tests.","Avoid duck-typed custom splitters; subclass TextSplitter."],"tags":["python","apache-beam","typeerror","langchain","argument-validation"],"backgroundTag":"invalid-argument-value","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}