{"record":{"id":"8b2fd8bd897d6581","repo":"zylon-ai/private-gpt","slug":"remotetokenizetokenizer-only-supports-text-tokeniz","errorCode":null,"errorMessage":"RemoteTokenizeTokenizer only supports text tokenization","messagePattern":"RemoteTokenizeTokenizer only supports text tokenization","errorType":"exception","errorClass":"NotImplementedError","httpStatus":null,"severity":"error","filePath":"private_gpt/components/llm/tokenizers/remote.py","lineNumber":109,"sourceCode":"\n    @property\n    def is_multimodal(self) -> bool:\n        return False\n\n    def __call__(\n        self,\n        texts: TextLike | None = None,\n        images: ImageLike | None = None,\n        audios: AudioLike | None = None,\n        add_special_tokens: bool = True,\n        truncation: bool = False,\n        max_length: int | None = None,\n        **kwargs: Any,\n    ) -> TokenizedInput:\n        del add_special_tokens, truncation, max_length, kwargs\n\n        if images or audios:\n            raise NotImplementedError(\n                \"RemoteTokenizeTokenizer only supports text tokenization\"\n            )\n        if texts is None:\n            return TokenizedInput(input_ids=[])\n\n        if isinstance(texts, str):\n            return TokenizedInput(input_ids=self.encode(texts))\n\n        if isinstance(texts, Sequence):\n            input_ids: list[int] = []\n            for text in texts:\n                input_ids.extend(self.encode(str(text)))\n            return TokenizedInput(input_ids=input_ids)\n\n        return TokenizedInput(input_ids=self.encode(str(texts)))\n\n    def get_vocab(self) -> dict[str, int]:\n        raise NotImplementedError(","sourceCodeStart":91,"sourceCodeEnd":127,"githubUrl":"https://github.com/zylon-ai/private-gpt/blob/4a030776a31a901ad80b1bf4d7faa2c1a367efbb/private_gpt/components/llm/tokenizers/remote.py#L91-L127","documentation":"Raised by RemoteTokenizeTokenizer.tokenize (the sync path) when the call includes images or audios. The remote tokenizer protocol only handles text — the implementation explicitly deletes add_special_tokens/truncation/max_length kwargs and rejects any non-text payload with NotImplementedError. Any multimodal content must be tokenized elsewhere (e.g. by the embedding/multimodal pipeline), not by this tokenizer.","triggerScenarios":"Calling tokenizer.tokenize(texts=..., images=[...]) or tokenizer.tokenize(texts=..., audios=[...]) on a RemoteTokenizeTokenizer instance; routing mixed-mode content (image + caption) through the text tokenizer; a generic call site that always forwards all modality arguments even when they are empty is fine, but any truthy images/audios value raises.","commonSituations":"Upgrading a pipeline to multimodal ingestion while keeping tokenizer_mode=remote_tokenize; a shared helper that passes image/audio placeholders unconditionally; testing the tokenizer with multimodal fixtures.","solutions":["Remove images/audios from the tokenize() call and pass only texts (or None).","Tokenize non-text modalities with a multimodal-aware component instead of the remote text tokenizer.","Switch tokenizer_mode to an implementation that supports the modalities you need, if one exists.","Guard call sites: forward images/audios only when non-empty."],"exampleFix":"# before\nresult = tok.tokenize(texts=prompt, images=[img_bytes])  # NotImplementedError\n\n# after\ntext_result = tok.tokenize(texts=prompt)\n# handle img_bytes via the multimodal embedding path","handlingStrategy":"validation","validationCode":"def tokenize_safe(tok, texts=None, images=None, audios=None):\n    if getattr(tok, 'remote_only_text', False) and (images or audios):\n        raise SkipModality('use multimodal counter for non-text')\n    return tok.tokenize(texts=texts)","typeGuard":"def supports_multimodal(tok) -> bool:\n    return 'RemoteTokenizeTokenizer' not in type(tok).__name__","tryCatchPattern":"try:\n    result = tok.tokenize(texts=t, images=imgs)\nexcept NotImplementedError:\n    result = tok.tokenize(texts=t)  # count images separately","preventionTips":["Only forward images/audios kwargs when truthy and when the tokenizer is known to support them.","Keep a modality-aware dispatcher at the pipeline level so text and non-text content never share one tokenizer call."],"tags":["tokenizer","multimodal","not-implemented","validation"],"backgroundTag":null,"analyzedSha":"4a030776a31a901ad80b1bf4d7faa2c1a367efbb","analyzedAt":"2026-08-15T03:51:26.951Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}