{"record":{"id":"aa2eadf5863c8130","repo":"apache/beam","slug":"side-inputs-must-have-defaults-for-maptuple","errorCode":null,"errorMessage":"Side inputs must have defaults for MapTuple.","messagePattern":"Side inputs must have defaults for MapTuple\\.","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"sdks/python/apache_beam/transforms/core.py","lineNumber":2204,"sourceCode":"    A :class:`~apache_beam.pvalue.PCollection` containing the\n    :func:`MapTuple` outputs.\n\n  Raises:\n    TypeError: If the **fn** passed as argument is not a callable.\n      Typical error is to pass a :class:`DoFn` instance which is supported only\n      for :class:`ParDo`.\n  \"\"\"\n  if not callable(fn):\n    raise TypeError(\n        'MapTuple can be used only with callable objects. '\n        'Received %r instead.' % (fn))\n\n  label = 'MapTuple(%s)' % ptransform.label_from_callable(fn)\n\n  arg_names, defaults = get_function_args_defaults(fn)\n  num_defaults = len(defaults)\n  if num_defaults < len(args) + len(kwargs):\n    raise TypeError('Side inputs must have defaults for MapTuple.')\n\n  if defaults or args or kwargs:\n    wrapper = lambda x, *args, **kwargs: [fn(*(tuple(x) + args), **kwargs)]\n  else:\n    wrapper = lambda x: [fn(*x)]\n\n  # Proxy the type-hint information from the original function to this new\n  # wrapped function.\n  type_hints = get_type_hints(fn).with_defaults(\n      typehints.decorators.IOTypeHints.from_callable(fn))\n  if type_hints.input_types is not None:\n    # TODO(BEAM-14052): ignore input hints, as we do not have enough\n    # information to infer the input type hint of the wrapper function.\n    pass\n  output_hint = type_hints.simple_output_type(label)\n  if output_hint:\n    tagged = {\n        k: typehints.Iterable[v]","sourceCodeStart":2186,"sourceCodeEnd":2222,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/python/apache_beam/transforms/core.py#L2186-L2222","documentation":"MapTuple spreads the input tuple plus side inputs as positional args to fn. Each side input must correspond to a parameter of fn that has a default value, because the wrapper may be invoked with fewer positional args when side inputs are deferred. If the number of defaulted parameters is smaller than args+kwargs (side inputs), Beam raises TypeError.","triggerScenarios":"beam.MapTuple(fn, 'side_input_label', other_label) where fn's signature has fewer parameters with defaults than the number of side inputs passed.","commonSituations":"Adding a side input with pvalue.AsDict/AsIter without extending fn's signature with default-valued parameters; side inputs added by someone else later; converting Map to MapTuple without adjusting the signature.","solutions":["Give each side-input parameter a default value in fn, e.g. def fn(k, v, extra=None): ...","Reduce the number of side inputs to match the number of defaulted parameters.","Switch to beam.Map / beam.ParDo if you need explicit side-input handling without defaults.","Rename side input usage so positional/keyword side inputs bind to fn's defaulted args (use kwargs for named side inputs)."],"exampleFix":"// before\ndef fn(k, v, scale): ...  # no default\nbeam.MapTuple(fn, 'scale_label')\n// after\ndef fn(k, v, scale=1.0): ...\nbeam.MapTuple(fn, 'scale_label')","handlingStrategy":"validation","validationCode":"from apache_beam.transforms.ptransform import get_function_args_defaults\narg_names, defaults = get_function_args_defaults(fn)\nnum_defaults = len(defaults)\nassert num_defaults >= len(args) + len(kwargs), 'need a defaulted param per side input for MapTuple'","typeGuard":"def side_inputs_have_defaults(fn, args, kwargs):\n    return len(get_function_args_defaults(fn)[1]) >= len(args) + len(kwargs)","tryCatchPattern":"try:\n    out = pcoll | beam.MapTuple(fn, *side_labels)\nexcept TypeError as e:\n    if 'defaults for MapTuple' in str(e):\n        raise ValueError('Add default values to fn params for each side input') from e\n    raise","preventionTips":["When adding a side input, add a keyword-with-default parameter to the fn.","Prefer keyword side inputs bound to defaulted kwargs.","Review signature changes with the side-input call sites together."],"tags":["python","apache-beam","maptuple","side-inputs"],"backgroundTag":"missing-required-argument","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"}