apache/beam · error · TypeCheckError

Unexpected VAR_POSITIONAL value

Error message

Unexpected VAR_POSITIONAL value: %s

What it means

_normalize_var_positional_hint normalizes the hint recorded for a *args parameter into a variadic Tuple[<type>, ...]. It expects a non-empty tuple of hint constraints; anything else (None, empty tuple, a list, a single non-tuple constraint) raises TypeCheckError.

Solutions

  1. Wrap the *args hint in a one-element tuple: (Tuple[int, ...],) so the normalization branch len(hint)==1 with TupleSequenceConstraint applies
  2. For mixed *args use tuple(int, str) form — i.e. pass (int, str) as the hint tuple
  3. Inspect how the hint was attached (with_input_types vs TypeHintVisitor) and use the decorator API instead of hand-built structures
  4. Upgrade Beam if hints were produced by an older serialization path

Example fix

// before
hints = IOTypeHints(..., var_positional_arg=int)
// after
hints = IOTypeHints(..., var_positional_arg=(int,))  # or (Tuple[int, ...],)
Defensive patterns

Strategy: validation

Validate before calling

def is_valid_var_positional(h):
  return isinstance(h, tuple) and len(h) >= 1

Try / catch

try:
  args = getcallargs_forhints(fn, hints)
except TypeCheckError as e:
  log.error('bad VAR_POSITIONAL hint: %s', e)

Prevention

When it happens

Trigger: Calling getcallargs_forhints on a function with a *args parameter whose recorded hint is not a tuple of constraints — e.g. hint stored as a single type int, an empty tuple, or None because the hint registry was populated incorrectly.

Common situations: Manually constructing IOTypeHints and passing a bare type instead of (type,) for VAR_POSITIONAL; bug in custom hint plumbing that forgets to wrap the variadic hint in a tuple; older serialized hints migrated across Beam versions.

Understand the failure class

Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.

Related errors


AI-assisted analysis of apache/beam@12126d8942 (2026-09-13). Data as JSON: /api/errors/7ce78f3fd3c83f3a. Report an issue: GitHub.

Appendix: source

Thrown at sdks/python/apache_beam/typehints/decorators.py:724

      return tuple(
          _unpack_positional_arg_hints(a, t)
          for a, t in zip(arg, hint.tuple_types))
    return (typehints.Any, ) * len(arg)
  return hint


def _normalize_var_positional_hint(hint):
  """Converts a var_positional hint into Tuple[Union[<types>], ...] form.

  Args:
    hint: (tuple) Should be either a tuple of one or more types, or a single
      Tuple[<type>, ...].

  Raises:
    TypeCheckError if hint does not have the right form.
  """
  if not hint or type(hint) != tuple:
    raise TypeCheckError('Unexpected VAR_POSITIONAL value: %s' % hint)

  if len(hint) == 1 and isinstance(hint[0], typehints.TupleSequenceConstraint):
    # Example: tuple(Tuple[Any, ...]) -> Tuple[Any, ...]
    return hint[0]
  else:
    # Example: tuple(int, str) -> Tuple[Union[int, str], ...]
    return typehints.Tuple[typehints.Union[hint], ...]


def _normalize_var_keyword_hint(hint, arg_name):
  """Converts a var_keyword hint into Dict[<key type>, <value type>] form.

  Args:
    hint: (dict) Should either contain a pair (arg_name,
      Dict[<key type>, <value type>]), or one or more possible types for the
      value.
    arg_name: (str) The keyword receiving this hint.

View on GitHub (pinned to 12126d8942)