{"record":{"id":"9d7d69d4b4828161","repo":"zylon-ai/private-gpt","slug":"no-reader-available-for-extension-extension","errorCode":null,"errorMessage":"No reader available for extension: {extension}","messagePattern":"No reader available for extension: (.+?)","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"private_gpt/components/readers/reader_component.py","lineNumber":43,"sourceCode":"    ) -> None:\n        self.settings = settings\n        self.registry = reader_registry\n        self.factory_registry = reader_factory_registry\n\n    def get_reader_by_extension(self, extension: str) -> IngestionReader:\n        reader_names = self.get_reader_names(extension=extension)\n        if not reader_names:\n            raise ValueError(f\"No reader registered for extension: {extension}\")\n        return self.get_reader(reader_names[0], extension)\n\n    def get_reader(\n        self,\n        name: str | None = None,\n        extension: str | None = None,\n    ) -> IngestionReader:\n        reader_names = self.get_reader_names(name=name, extension=extension)\n        if not reader_names:\n            raise ValueError(f\"No reader available for extension: {extension}\")\n        target_name = reader_names[0]\n        factory = self.factory_registry.get_factory(target_name)\n        return factory.create_reader(extension)\n\n    def get_registered_reader_name(self, extension: str | None) -> str | None:\n        return self.registry.get_reader_name(extension)\n\n    def get_reader_names(\n        self,\n        name: str | None = None,\n        extension: str | None = None,\n    ) -> list[str]:\n        if name and name != \"auto\":\n            return [name]\n\n        reader_names = self.registry.get_reader_names(extension)\n        if self.settings.data.reader in reader_names:\n            reader_names = [self.settings.data.reader]","sourceCodeStart":25,"sourceCodeEnd":61,"githubUrl":"https://github.com/zylon-ai/private-gpt/blob/4a030776a31a901ad80b1bf4d7faa2c1a367efbb/private_gpt/components/readers/reader_component.py#L25-L61","documentation":"ReaderComponent.get_reader(name, extension) resolves a reader by optional name and/or extension; when the combined filter yields no reader names it raises ValueError ('No reader available...'). Unlike error 203 (pure extension lookup), this fires when a name filter excludes all candidates or the extension lookup is combined with a name that does not match anything registered.","triggerScenarios":"Calling get_reader(name=\"some_reader\", extension=\".foo\") where no registered reader matches both filters; calling get_reader(extension=ext) for an unregistered extension through this method; passing a factory name that was never registered or was unregistered.","commonSituations":"Requesting a named reader that a plugin failed to register; passing a stale reader name after a version upgrade renamed readers; combining a valid extension with a mismatched name filter; unregistering a factory dynamically and then requesting it.","solutions":["List the actual candidates first: `component.get_reader_names(name=name, extension=extension)` and use a returned name.","If you don't need a specific reader, drop the name filter and call get_reader_by_extension(ext).","Register the missing reader factory under the exact name you request (register_reader_factory).","Check for typos/case mismatch in the reader name string."],"exampleFix":"# before\nreader = component.get_reader(name=\"PdfReader\", extension=\".pdf\")  # ValueError\n\n# after\nnames = component.get_reader_names(extension=\".pdf\")\nreader = component.get_reader(name=names[0], extension=\".pdf\") if names else None","handlingStrategy":"validation","validationCode":"names = component.get_reader_names(name=name, extension=extension)\nif not names:\n    raise HTTPException(400, f\"No reader for name={name!r}, extension={extension!r}\")\nreader = component.get_reader(name=names[0], extension=extension)","typeGuard":null,"tryCatchPattern":"try:\n    reader = component.get_reader(name, extension)\nexcept ValueError as e:\n    logger.warning(\"Reader resolution failed: %s\", e)\n    reader = component.get_reader_by_extension(extension)  # name-less fallback","preventionTips":["Always resolve via get_reader_names first and use a returned name verbatim.","Treat reader names as config pinned per deployment; validate them at startup.","Avoid hard-coded reader names that can drift across upgrades."],"tags":["ingestion","reader-registry","file-type","validation"],"backgroundTag":null,"analyzedSha":"4a030776a31a901ad80b1bf4d7faa2c1a367efbb","analyzedAt":"2026-08-15T03:51:26.951Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}