{"record":{"id":"8aac90b6e2bdfd20","repo":"apache/beam","slug":"not-a-kv-coder-s","errorCode":null,"errorMessage":"Not a KV coder: %s.","messagePattern":"Not a KV coder: (.+?)\\.","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"sdks/python/apache_beam/coders/coders.py","lineNumber":263,"sourceCode":"    # 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.\n    return []\n","sourceCodeStart":245,"sourceCodeEnd":281,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/python/apache_beam/coders/coders.py#L245-L281","documentation":"Coder.key_coder in apache_beam.coders is only valid on KV coders: for a non-KV coder, is_kv_coder() is False and this ValueError fires (while the KV-coder branch would raise NotImplementedError). It is a type guard ensuring callers only extract key coders from coders that actually encode key/value pairs; here it is reached from key_coder during coder composition.","triggerScenarios":"Calling coder.key_coder() on a non-KV coder (is_kv_coder() False), e.g. BytesCoder or a custom coder, from code that assumes elements are (key, value) tuples.","commonSituations":"Pipeline/framework code extracting key coders from arbitrary coders; users applying KV-only transforms to PCollection elements that are not key/value pairs.","solutions":["Only call key_coder() after checking coder.is_kv_coder()","Use TupleCoder or a KV-aware coder for key/value data","Restructure so key/value coders are obtained from the coder registry for KV PCollections"],"exampleFix":"// before\nkc = coder.key_coder()  # coder may not be KV\n// after\nkc = coder.key_coder() if coder.is_kv_coder() else None","handlingStrategy":"validation","validationCode":"if not coder.is_kv_coder():\n    raise ValueError('expected a KV coder, got %s' % coder)","typeGuard":"def is_kv(coder):\n    return coder.is_kv_coder()","tryCatchPattern":"try:\n    kc = coder.key_coder()\nexcept ValueError as e:\n    log.error('%s', e)\n    kc = None","preventionTips":["Check is_kv_coder() before requesting key/value coders","Use KV coders for KV-shaped PCollections","Avoid assuming every element coder is decomposable"],"tags":["python","apache-beam","coders","kv"],"backgroundTag":"invalid-argument-value","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"}