{"record":{"id":"a4d7b5edb0a1cccd","repo":"apache/beam","slug":"parameter-to-kv-type-hint-must-be-a-tuple-of-types-kv","errorCode":null,"errorMessage":"Parameter to KV type-hint must be a tuple of types: KV[.., ..].","messagePattern":"Parameter to KV type-hint must be a tuple of types: KV\\[\\.\\., \\.\\.\\]\\.","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"sdks/python/apache_beam/typehints/typehints.py","lineNumber":824,"sourceCode":"  def __getitem__(self, t):\n    validate_composite_type_param(t, error_msg_prefix='Parameter to List hint')\n\n    return self.ListConstraint(t)\n\n\nListConstraint = ListHint.ListConstraint\n\n\nclass KVHint(CompositeTypeHint):\n  \"\"\"A KV type-hint, represents a Key-Value pair of a particular type.\n\n  Internally, KV[X, Y] proxies to Tuple[X, Y]. A KV type-hint accepts only\n  accepts exactly two type-parameters. The first represents the required\n  key-type and the second the required value-type.\n  \"\"\"\n  def __getitem__(self, type_params):\n    if not isinstance(type_params, tuple):\n      raise TypeError(\n          'Parameter to KV type-hint must be a tuple of types: '\n          'KV[.., ..].')\n\n    if len(type_params) != 2:\n      raise TypeError(\n          'Length of parameters to a KV type-hint must be exactly 2. Passed '\n          'parameters: %s, have a length of %s.' %\n          (type_params, len(type_params)))\n\n    return Tuple[type_params]\n\n\ndef key_value_types(kv):\n  \"\"\"Returns the key and value type of a KV type-hint.\n\n  Args:\n    kv: An instance of a TypeConstraint sub-class.\n  Returns:","sourceCodeStart":806,"sourceCodeEnd":842,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/python/apache_beam/typehints/typehints.py#L806-L842","documentation":"KVHint.__getitem__ is a type guard on subscripted KV[...] hints: the parameters must be passed as a 2-tuple of types (KV[K, V]). Python delivered a single bare type instead of a tuple because the hint was written without a comma, e.g. KV[str] rather than KV[str, int].","triggerScenarios":"KV[int] (single param); KV[int, str, bool] without parentheses is actually KV[(int, str, bool)] — fine — but KV[int, str] written as a non-tuple like KV[[int, str]] or a generator/list.","commonSituations":"Typos like KV[int, str] where one arg is itself a list; dynamically building type parameters and passing a list instead of a tuple.","solutions":["Pass exactly two parameters: KV[int, str]","If parameters are dynamic, pass a 2-tuple: KV[tuple(params)] with len==2","Use Tuple[...] directly if key/value semantics are not needed"],"exampleFix":"# before\nKV([int, str])\n# after\nKV[int, str]","handlingStrategy":"type-guard","validationCode":"assert isinstance(params, tuple), 'KV requires a tuple of types'","typeGuard":"def valid_kv_params(p): return isinstance(p, tuple) and len(p) == 2","tryCatchPattern":null,"preventionTips":["Always subscript KV with two literal types","In dynamic builders, coerce with tuple(params) and assert len==2"],"tags":["python","apache-beam","type-hints","kv"],"backgroundTag":"invalid-argument-format","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"}