{"record":{"id":"c59a8716eaf0e7af","repo":"apache/beam","slug":"expecting-type-s-to-have-arity-d-had-arity-d-instead","errorCode":null,"errorMessage":"expecting type %s to have arity %d, had arity %d instead","messagePattern":"expecting type (.+?) to have arity (.+?), had arity (.+?) instead","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"sdks/python/apache_beam/typehints/native_type_compatibility.py","lineNumber":542,"sourceCode":"    elif (_match_issubclass(typing.Iterator)(typ) or\n          _match_is_exactly_iterable(typ)):\n      args = (typehints.TypeVariable('T_co'), )\n    else:\n      args = (typehints.TypeVariable('T'), ) * arity\n  elif matched_entry.arity == -1:\n    arity = len_args\n  # Counters are special dict types that are implicitly parameterized to\n  # [T, int], so we fix cases where they only have one argument to match\n  # a more traditional dict hint.\n  elif len_args == 1 and _safe_issubclass(getattr(typ, '__origin__', typ),\n                                          collections.Counter):\n    args = (args[0], int)\n    len_args = 2\n    arity = matched_entry.arity\n  else:\n    arity = matched_entry.arity\n    if len_args != arity:\n      raise ValueError(\n          'expecting type %s to have arity %d, had arity %d '\n          'instead' % (str(typ), arity, len_args))\n  typs = convert_to_beam_types(args)\n  if arity == 0:\n    # Nullary types (e.g. Any) don't accept empty tuples as arguments.\n    return matched_entry.beam_type\n  elif arity == 1:\n    # Unary types (e.g. Set) don't accept 1-tuples as arguments\n    return matched_entry.beam_type[typs[0]]\n  else:\n    return matched_entry.beam_type[tuple(typs)]\n\n\ndef convert_to_beam_types(args):\n  \"\"\"Convert the given list or dictionary of args to Beam types.\n\n  Args:\n    args: Either an iterable of types, or a dictionary where the values are","sourceCodeStart":524,"sourceCodeEnd":560,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/python/apache_beam/typehints/native_type_compatibility.py#L524-L560","documentation":"In Apache Beam's Python SDK, convert_to_beam_type maps Python native typing constructs to internal Beam type objects via a lookup table of matched entries, each with an expected arity (number of type parameters). This ValueError is raised when a typing construct's number of type arguments does not match the arity recorded for it in the compatibility mapping table. It guards against malformed or unsupported typing expressions such as wrong subscript counts.","triggerScenarios":"Calling convert_to_beam_type (directly or via from_callable, with_output_types, or _extract_tagged_from_type) with a typing generic whose subscription argument count disagrees with the mapping table's arity, e.g. a nullary or multi-arg special form passed with the wrong number of parameters.","commonSituations":"Annotating DoFn process methods or ParDo with_output_types with unusual/legacy typing constructs (e.g. typing.Sequence with two parameters, or Any subscripted), often after a Python version upgrade changed typing internals.","solutions":["Fix the type annotation so the number of type parameters matches the construct (e.g. Any takes no parameters: use typing.Any, not typing.Any[x]).","Replace the unsupported typing construct with an equivalent standard generic supported by Beam (List[int], Sequence[str], Tuple[...], etc.).","If converting many types, pre-check the count of __args__ on the typing object before calling convert_to_beam_type and catch ValueError as a fallback.","Check the Beam version's native_type_compatibility mapping table (MATCHED_ENTRIES) to confirm the expected arity for the construct."],"exampleFix":"// before\nbeam_type = convert_to_beam_type(typing.Any[str])  # arity mismatch\n// after\nbeam_type = convert_to_beam_type(typing.Any)  # nullary, matches expected arity 0","handlingStrategy":"validation","validationCode":"def is_safe_for_beam(typ):\n    args = typing.get_args(typ)\n    if typing.get_origin(typ) is None:\n        return True\n    # Any and other nullary forms take no args\n    if typ is typing.Any:\n        return len(args) == 0\n    return len(args) in (1, 2)  # typical supported arities\n","typeGuard":"def is_supported_typing_generic(typ) -> bool:\n    return hasattr(typ, '__origin__') and hasattr(typ, '__args__')\n","tryCatchPattern":"try:\n    beam_type = convert_to_beam_type(typ)\nexcept ValueError as e:\n    logging.warning('Falling back to Any for type %r: %s', typ, e)\n    beam_type = typehints.Any\n","preventionTips":["Use standard typing generics (List, Dict, Sequence, Tuple, Union) in pipeline annotations.","Never subscript nullary forms like typing.Any.","Pin and test the Beam SDK version alongside your Python version; typing internals change across versions.","Add unit tests that call convert_to_beam_type on all annotations used in your pipeline."],"tags":["python","apache-beam","type-hints","typing"],"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-14T11:17:12.474Z"}