{"record":{"id":"98429d89fbc2dae8","repo":"apache/beam","slug":"side-inputs-must-have-defaults-for-flatmaptuple","errorCode":null,"errorMessage":"Side inputs must have defaults for FlatMapTuple.","messagePattern":"Side inputs must have defaults for FlatMapTuple\\.","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"sdks/python/apache_beam/transforms/core.py","lineNumber":2282,"sourceCode":"    A :class:`~apache_beam.pvalue.PCollection` containing the\n    :func:`FlatMapTuple` 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        'FlatMapTuple can be used only with callable objects. '\n        'Received %r instead.' % (fn))\n\n  label = 'FlatMapTuple(%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 FlatMapTuple.')\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(*tuple(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    wrapper = with_output_types(\n        _strip_output_annotations(output_hint, strip_tagged_output=False),","sourceCodeStart":2264,"sourceCodeEnd":2300,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/python/apache_beam/transforms/core.py#L2264-L2300","documentation":"FlatMapTuple spreads the input tuple plus side inputs positionally into fn. As with MapTuple, every side input must map onto a fn parameter with a default value (since deferred side inputs can arrive as fewer positional args). Fewer defaults than side inputs raises this TypeError.","triggerScenarios":"beam.FlatMapTuple(fn, side_label1, side_label2) where fn has fewer default-valued parameters than 2 side inputs.","commonSituations":"Adding side inputs (AsIter/AsDict/AsSingleton) without adding defaulted params to the function; refactoring from ParDo (where side inputs are declared via __process__) to FlatMapTuple; team conventions mismatch on how side inputs bind.","solutions":["Add default values to fn's parameters corresponding to each side input: def fn(k, v, extra=None, cfg=None): ...","Pass fewer side inputs, matching existing defaulted parameters.","Switch to beam.ParDo if you need DoFn-style side input access without defaults.","Use keyword side inputs mapped to fn's keyword-with-default parameters instead of positional."],"exampleFix":"// before\ndef fn(k, v, limit): ...  # missing default\nbeam.FlatMapTuple(fn, 'limit_label')\n// after\ndef fn(k, v, limit=10): ...\nbeam.FlatMapTuple(fn, 'limit_label')","handlingStrategy":"validation","validationCode":"from apache_beam.transforms.ptransform import get_function_args_defaults\narg_names, defaults = get_function_args_defaults(fn)\nassert len(defaults) >= len(args) + len(kwargs), 'need a defaulted param per side input for FlatMapTuple'","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.FlatMapTuple(fn, *side_labels)\nexcept TypeError as e:\n    if 'defaults for FlatMapTuple' in str(e):\n        raise ValueError('Add default values to fn params for each side input') from e\n    raise","preventionTips":["Every side input needs a matching fn parameter with a default.","Test transforms with deferred side inputs to surface binding issues.","Keep side-input count and fn signature changes in the same commit."],"tags":["python","apache-beam","flatmaptuple","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"}