zylon-ai/private-gpt · error · ValueError

No reader available for extension: {extension}

Error message

No reader available for extension: {extension}

What it means

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.

Source

Thrown at private_gpt/components/readers/reader_component.py:43

    ) -> None:
        self.settings = settings
        self.registry = reader_registry
        self.factory_registry = reader_factory_registry

    def get_reader_by_extension(self, extension: str) -> IngestionReader:
        reader_names = self.get_reader_names(extension=extension)
        if not reader_names:
            raise ValueError(f"No reader registered for extension: {extension}")
        return self.get_reader(reader_names[0], extension)

    def get_reader(
        self,
        name: str | None = None,
        extension: str | None = None,
    ) -> IngestionReader:
        reader_names = self.get_reader_names(name=name, extension=extension)
        if not reader_names:
            raise ValueError(f"No reader available for extension: {extension}")
        target_name = reader_names[0]
        factory = self.factory_registry.get_factory(target_name)
        return factory.create_reader(extension)

    def get_registered_reader_name(self, extension: str | None) -> str | None:
        return self.registry.get_reader_name(extension)

    def get_reader_names(
        self,
        name: str | None = None,
        extension: str | None = None,
    ) -> list[str]:
        if name and name != "auto":
            return [name]

        reader_names = self.registry.get_reader_names(extension)
        if self.settings.data.reader in reader_names:
            reader_names = [self.settings.data.reader]

View on GitHub (pinned to 4a030776a3)

Solutions

  1. List the actual candidates first: `component.get_reader_names(name=name, extension=extension)` and use a returned name.
  2. If you don't need a specific reader, drop the name filter and call get_reader_by_extension(ext).
  3. Register the missing reader factory under the exact name you request (register_reader_factory).
  4. Check for typos/case mismatch in the reader name string.

Example fix

# before
reader = component.get_reader(name="PdfReader", extension=".pdf")  # ValueError

# after
names = component.get_reader_names(extension=".pdf")
reader = component.get_reader(name=names[0], extension=".pdf") if names else None
Defensive patterns

Strategy: validation

Validate before calling

names = component.get_reader_names(name=name, extension=extension)
if not names:
    raise HTTPException(400, f"No reader for name={name!r}, extension={extension!r}")
reader = component.get_reader(name=names[0], extension=extension)

Try / catch

try:
    reader = component.get_reader(name, extension)
except ValueError as e:
    logger.warning("Reader resolution failed: %s", e)
    reader = component.get_reader_by_extension(extension)  # name-less fallback

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of zylon-ai/private-gpt@4a030776a3 (2026-08-15). Data as JSON: /api/errors/9d7d69d4b4828161. Report an issue: GitHub.