{"record":{"id":"2b8c36631024560d","repo":"apache/beam","slug":"key-coder-s","errorCode":null,"errorMessage":"key_coder: %s","messagePattern":"key_coder: (.+?)","errorType":"exception","errorClass":"NotImplementedError","httpStatus":null,"severity":"error","filePath":"sdks/python/apache_beam/coders/coders.py","lineNumber":261,"sourceCode":"    # TODO: After https://github.com/apache/beam/issues/18490 we should be\n    # able to infer the type hint rather than require every subclass define\n    # it\n    raise NotImplementedError\n\n  @classmethod\n  def from_type_hint(cls, unused_typehint, unused_registry):\n    # type: (Type[CoderT], Any, CoderRegistry) -> CoderT\n    # If not overridden, just construct the coder without arguments.\n    return cls()\n\n  def is_kv_coder(self):\n    # type: () -> bool\n    return False\n\n  def key_coder(self):\n    # type: () -> Coder\n    if self.is_kv_coder():\n      raise NotImplementedError('key_coder: %s' % self)\n    else:\n      raise ValueError('Not a KV coder: %s.' % self)\n\n  def value_coder(self):\n    # type: () -> Coder\n    if self.is_kv_coder():\n      raise NotImplementedError('value_coder: %s' % self)\n    else:\n      raise ValueError('Not a KV coder: %s.' % self)\n\n  def _get_component_coders(self):\n    # type: () -> Sequence[Coder]\n\n    \"\"\"For internal use only; no backwards-compatibility guarantees.\n\n    Returns the internal component coders of this coder.\"\"\"\n    # This is an internal detail of the Coder API and does not need to be\n    # refined in user-defined Coders.","sourceCodeStart":243,"sourceCodeEnd":279,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/python/apache_beam/coders/coders.py#L243-L279","documentation":"Coder.key_coder() raises NotImplementedError when is_kv_coder() is True but the coder has no key-component notion implemented (base-class default), i.e. the coder claims to be a KV coder yet does not provide a key coder. It raises ValueError('Not a KV coder') otherwise.","triggerScenarios":"Calling key_coder() on a custom Coder whose is_kv_coder() returns True (default True in some paths) but which does not override _get_component_coders/key_coder; base Coder instances used where the framework asks for the key coder (e.g. for grouping).","commonSituations":"Custom coders for KV-shaped values that never implemented the component coder API; runner code or user code probing coders for key/value split on non-KV-aware coders.","solutions":["Override key_coder()/value_coder() or _get_component_coders() in your custom coder","Use a concrete KV coder (e.g. coders.TupleCoder) that supplies component coders","Ensure is_kv_coder() accurately reflects your coder (return False if it is not a KV coder)"],"exampleFix":"// before\nclass MyCoder(Coder):\n    def is_kv_coder(self):\n        return True\n// after\nclass MyCoder(Coder):\n    def is_kv_coder(self):\n        return False\n    # or implement:\n    def key_coder(self):\n        return coders.BytesCoder()","handlingStrategy":"type-guard","validationCode":"if coder.is_kv_coder() and type(coder).key_coder is Coder.key_coder:\n    raise TypeError('coder claims KV but lacks key_coder')","typeGuard":"def has_key_coder(coder):\n    return coder.is_kv_coder() and type(coder).key_coder is not Coder.key_coder","tryCatchPattern":"try:\n    kc = coder.key_coder()\nexcept NotImplementedError as e:\n    log.error('no key coder for %s: %s', coder, e)\n    kc = default_key_coder","preventionTips":["Override key_coder/value_coder in custom KV coders","Keep is_kv_coder() honest for custom coders","Prefer TupleCoder for key/value data"],"tags":["python","apache-beam","coders","kv"],"backgroundTag":"method-not-implemented","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}