docling-project/docling · error · KeyError

Preset '{preset_id}' not found for {cls.__name__}. Available

Error message

Preset '{preset_id}' not found for {cls.__name__}. Available presets: {list(cls._presets.keys())}

What it means

Stage classes using the generic preset mixin expose get_preset(preset_id), which raises KeyError when the requested preset id is not in the class's registered _presets registry. Presets are registered explicitly via register_preset, so an unknown or unregistered id — including typos and version-removed presets — fails here. The message lists the available preset ids for that class.

Source

Thrown at docling/datamodel/stage_model_specs.py:581

            _log.error(
                f"Preset '{preset.preset_id}' already registered for {cls.__name__}"
            )

    @classmethod
    def get_preset(cls, preset_id: str) -> StageModelPreset:
        """Get a specific preset.

        Args:
            preset_id: The preset identifier

        Returns:
            The requested preset

        Raises:
            KeyError: If preset not found
        """
        if preset_id not in cls._presets:
            raise KeyError(
                f"Preset '{preset_id}' not found for {cls.__name__}. "
                f"Available presets: {list(cls._presets.keys())}"
            )
        return cls._presets[preset_id]

    @classmethod
    def list_presets(cls) -> List[StageModelPreset]:
        """List all presets for this stage.

        Returns:
            List of presets
        """
        return list(cls._presets.values())

    @classmethod
    def list_preset_ids(cls) -> List[str]:
        """List all preset IDs for this stage.

View on GitHub (pinned to 61d76f1ff3)

Solutions

  1. Read the available ids from the error message (or call list_preset_ids()) and use one of them.
  2. Fix the typo / renamed id in your config.
  3. If a custom preset is intended, register it first with register_preset(...), then call get_preset.

Example fix

# before
stage = MyStage.from_preset("accurat")  # typo

# after
print(MyStage.list_preset_ids())  # confirm valid ids
stage = MyStage.from_preset("accurate")
Defensive patterns

Strategy: validation

Validate before calling

def preset_exists(stage_cls, preset_id: str) -> bool:
    return preset_id in stage_cls.list_preset_ids()

if not preset_exists(MyStage, pid):
    raise ValueError(f"unknown preset {pid}; valid: {MyStage.list_preset_ids()}")

Type guard

def is_known_preset(stage_cls, preset_id: str) -> bool:
    return preset_id in stage_cls.list_preset_ids()

Try / catch

try:
    preset = MyStage.get_preset(pid)
except KeyError as e:
    candidates = difflib.get_close_matches(pid, MyStage.list_preset_ids(), n=1)
    raise ValueError(f"Unknown preset. Did you mean {candidates}?") from e

Prevention

When it happens

Trigger: Calling SomeStage.get_preset('my_preset') (or from_preset('my_preset')) where 'my_preset' was never registered on that class; using a preset id that exists on a different stage class; registering the preset after the lookup or not at all.

Common situations: Typos in preset ids from hand-written config strings; upgrading docling where a preset was renamed or removed; forgetting to call the registration code (e.g. a register_defaults()/import of the module that registers presets) before fetching.

Related errors


AI-assisted analysis of docling-project/docling@61d76f1ff3 (2026-08-14). Data as JSON: /api/errors/02b00d59d420c983. Report an issue: GitHub.