ocrmypdf/OCRmyPDF · warning · ValueError

Too many registry keys under {key}

Error message

Too many registry keys under {key}

What it means

A Windows-registry enumeration safety valve: registry_enum stops after `limit` keys and raises ValueError if it hit exactly that many, to avoid scanning unbounded or corrupt registry hives.

Source

Thrown at src/ocrmypdf/subprocess/_windows.py:61

        release = [int(elem) for elem in s.split('.', maxsplit=3)]
        while len(release) < 3:
            release.append(0)
        return (release[0], release[1], release[2])
    except ValueError:
        return (0, 0, 0)


def registry_enum(key: HKEYType, enum_fn: Callable[[HKEYType, int], T]) -> Iterator[T]:
    limit = 999
    n = 0
    while n < limit:
        try:
            yield enum_fn(key, n)
            n += 1
        except OSError:
            break
    if n == limit:
        raise ValueError(f"Too many registry keys under {key}")


def registry_subkeys(key: HKEYType) -> Iterator[str]:
    return registry_enum(key, winreg.EnumKey)


def registry_values(key: HKEYType) -> Iterator[tuple[str, Any, int]]:
    return registry_enum(key, winreg.EnumValue)


def _log_search_failure(what: str, where: str, e: OSError) -> None:
    """Explain a failed search for a program.

    Searching for programs in various places is speculative: most of the
    locations we check will not exist on any given machine, and finding the
    program in one of them means we never look at the rest. A failure here is
    only interesting when debugging why a program could not be found at all,
    so it must not be reported to the user as a warning. If every search

View on GitHub (pinned to 5074a0b0e1)

Solutions

  1. Pass a higher limit to registry_enum if the API allows
  2. Filter with a more specific registry path before enumerating
  3. If the key legitimately has many subkeys, page through with winreg.EnumKey directly in your own code

Example fix

# before
subs = list(registry_subkeys(key))
# after
subs = [winreg.EnumKey(key, i) for i in range(winreg.QueryInfoKey(key)[0]) if i < 1000]
Defensive patterns

Strategy: validation

Validate before calling

import winreg\nn = winreg.QueryInfoKey(key)[0]\nif n >= LIMIT:\n    raise ValueError(f'key has {n} subkeys; query directly instead')

Try / catch

try:\n    for name in registry_subkeys(key): ...\nexcept ValueError:\n    pass  # fall back to direct winreg.EnumKey loop

Prevention

When it happens

Trigger: Calling registry_subkeys/registry_values on a registry key that contains at least `limit` (default small cap) entries while running the Windows install-lookup code.

Common situations: Enumerating large registry keys (e.g. shell open-with or uninstall lists) when resolving file associations on Windows; the cap is conservative so legit large keys can trip it.


AI-assisted analysis of ocrmypdf/OCRmyPDF@5074a0b0e1 (2026-08-27). Data as JSON: /api/errors/a89f9bb4842503dc. Report an issue: GitHub.