{"record":{"id":"f2cc5131afbc4e6c","repo":"apache/beam","slug":"failed-to-generate-a-unique-uuid-for-schema-after-100-tries","errorCode":null,"errorMessage":"Failed to generate a unique UUID for schema after 100 tries! Registry contains {len(self.by_id)} schemas.","messagePattern":"Failed to generate a unique UUID for schema after 100 tries! Registry contains (.+?) schemas\\.","errorType":"exception","errorClass":"AssertionError","httpStatus":null,"severity":"error","filePath":"sdks/python/apache_beam/typehints/schema_registry.py","lineNumber":37,"sourceCode":"any backwards-compatibility guarantee.\n\"\"\"\n\nfrom uuid import uuid4\n\n\n# Registry of typings for a schema by UUID\nclass SchemaTypeRegistry(object):\n  def __init__(self):\n    self.by_id = {}\n    self.by_typing = {}  # currently not used\n\n  def generate_new_id(self):\n    for _ in range(100):\n      schema_id = str(uuid4())\n      if schema_id not in self.by_id:\n        return schema_id\n\n    raise AssertionError(\n        \"Failed to generate a unique UUID for schema after \"\n        f\"100 tries! Registry contains {len(self.by_id)} \"\n        \"schemas.\")\n\n  def add(self, typing, schema):\n    if schema.id:\n      self.by_id[schema.id] = (typing, schema)\n\n  def load_registered_typings(self, by_id):\n    for id, typing in by_id.items():\n      if id not in self.by_id:\n        self.by_id[id] = (typing, None)\n\n  def get_registered_typings(self):\n    # Used by save_main_session, as pb2.schema isn't picklable\n    return {k: v[0] for k, v in self.by_id.items()}\n\n  def get_typing_by_id(self, unique_id):","sourceCodeStart":19,"sourceCodeEnd":55,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/python/apache_beam/typehints/schema_registry.py#L19-L55","documentation":"The schema registry assigns each schema a UUID by retrying uuid4() up to 100 times until it finds one not already in by_id. If after 100 tries none were unique, it raises this AssertionError. In practice this means either a corrupted/poisoned registry (non-random uuid4, monkeypatched uuid) or an astronomically unlikely collision — with real uuid4 this is effectively an internal invariant violation.","triggerScenarios":"Calling `generate_new_id()` (indirectly via `SchemaRegistry.add` / creating a schema-aware type) while the registry's by_id dict is corrupted or uuid4 is patched to return a constant value present in the registry.","commonSituations":"Test suites monkeypatching uuid.uuid4 with deterministic stubs; custom UUID generators reused for many schemas; extremely large registries with a broken RNG.","solutions":["Stop stubbing/mocking uuid.uuid4 to return a fixed value in this process","Inspect the registry (len(by_id)) for duplicate/poisoned ids and clear it: SCHEMA_REGISTRY entries shouldn't collide for distinct schemas","Upgrade Beam; retrying 100 uuid4 draws failing is virtually impossible with a healthy RNG"],"exampleFix":"// before\nmock.patch('uuid.uuid4', return_value='fixed-id')  # 100 iterations all collide\n// after\nmock.patch('uuid.uuid4', side_effect=[str(uuid4()) for _ in range(100)])","handlingStrategy":"try-catch","validationCode":"if any(sid == str(uuid4()) for sid in registry.by_id):  # sanity check only\n  ...","typeGuard":null,"tryCatchPattern":"try:\n  schema_id = registry.generate_new_id()\nexcept AssertionError as e:\n  registry.clear(); schema_id = registry.generate_new_id()","preventionTips":["Never monkeypatch uuid.uuid4 to a constant in tests","Reset the schema registry between test cases if you stub RNGs"],"tags":["python","uuid","schema-registry","assertion"],"backgroundTag":"internal-invariant-violation","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-20T03:17:13.778Z"}