{"record":{"id":"a89f9bb4842503dc","repo":"ocrmypdf/OCRmyPDF","slug":"too-many-registry-keys-under-key","errorCode":null,"errorMessage":"Too many registry keys under {key}","messagePattern":"Too many registry keys under (.+?)","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"warning","filePath":"src/ocrmypdf/subprocess/_windows.py","lineNumber":61,"sourceCode":"        release = [int(elem) for elem in s.split('.', maxsplit=3)]\n        while len(release) < 3:\n            release.append(0)\n        return (release[0], release[1], release[2])\n    except ValueError:\n        return (0, 0, 0)\n\n\ndef registry_enum(key: HKEYType, enum_fn: Callable[[HKEYType, int], T]) -> Iterator[T]:\n    limit = 999\n    n = 0\n    while n < limit:\n        try:\n            yield enum_fn(key, n)\n            n += 1\n        except OSError:\n            break\n    if n == limit:\n        raise ValueError(f\"Too many registry keys under {key}\")\n\n\ndef registry_subkeys(key: HKEYType) -> Iterator[str]:\n    return registry_enum(key, winreg.EnumKey)\n\n\ndef registry_values(key: HKEYType) -> Iterator[tuple[str, Any, int]]:\n    return registry_enum(key, winreg.EnumValue)\n\n\ndef _log_search_failure(what: str, where: str, e: OSError) -> None:\n    \"\"\"Explain a failed search for a program.\n\n    Searching for programs in various places is speculative: most of the\n    locations we check will not exist on any given machine, and finding the\n    program in one of them means we never look at the rest. A failure here is\n    only interesting when debugging why a program could not be found at all,\n    so it must not be reported to the user as a warning. If every search","sourceCodeStart":43,"sourceCodeEnd":79,"githubUrl":"https://github.com/ocrmypdf/OCRmyPDF/blob/5074a0b0e109362422b768fd271ed84bf717c4ec/src/ocrmypdf/subprocess/_windows.py#L43-L79","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Pass a higher limit to registry_enum if the API allows","Filter with a more specific registry path before enumerating","If the key legitimately has many subkeys, page through with winreg.EnumKey directly in your own code"],"exampleFix":"# before\nsubs = list(registry_subkeys(key))\n# after\nsubs = [winreg.EnumKey(key, i) for i in range(winreg.QueryInfoKey(key)[0]) if i < 1000]","handlingStrategy":"validation","validationCode":"import winreg\\nn = winreg.QueryInfoKey(key)[0]\\nif n >= LIMIT:\\n    raise ValueError(f'key has {n} subkeys; query directly instead')","typeGuard":null,"tryCatchPattern":"try:\\n    for name in registry_subkeys(key): ...\\nexcept ValueError:\\n    pass  # fall back to direct winreg.EnumKey loop","preventionTips":["Narrow the registry path before enumerating","Query counts with QueryInfoKey first","Wrap registry scans in try/except on Windows"],"tags":["windows","registry","enumeration-limit"],"backgroundTag":"registry-enumeration-limit","analyzedSha":"5074a0b0e109362422b768fd271ed84bf717c4ec","analyzedAt":"2026-08-27T11:57:38.523Z","schemaVersion":2},"datasetVersion":"2026-08-27T13:17:12.746Z"}