apache/beam · error · ValueError

Index is out of bounds for obj.__defaults__ in path

Error message

Index {index} is out of bounds for obj.__defaults__ {len(obj.__defaults__)} in path {code_object_identifier}

What it means

When resolving a path segment matching the default-argument pattern, Beam indexes obj.__defaults__ with the parsed integer. If the index equals or exceeds the number of default values on the function/code object, ValueError is raised naming the index, its length, and the full path. The serialized default reference points at a slot that does not exist.

Solutions

  1. Verify len(func.__defaults__) covers the index: `assert i < len(f.__defaults__)` before calling.
  2. Regenerate the identifier after any change to the function's default arguments.
  3. Fix the index in the path (0-based) if it was constructed incorrectly.
  4. Replace default-value serialization with passing the value explicitly through the pipeline.

Example fix

// before
i = 2
get_code_from_identifier(f'mylib.f.__defaults__[{i}]')  # f has 1 default
// after
i = 0
assert i < len(mylib.f.__defaults__)
get_code_from_identifier(f'mylib.f.__defaults__[{i}]')
Defensive patterns

Strategy: validation

Validate before calling

import sys
def defaults_index_ok(path):
    head, _, seg = path.rpartition('.')
    if '__defaults__' not in seg or '[' not in seg: return True
    i = int(seg[seg.index('[')+1:-1])
    mod_name, _, rest = head.partition('.')
    obj = sys.modules[mod_name]
    for p in rest.split('.'): obj = getattr(obj, p)
    return i < len(getattr(obj, '__defaults__', ()))

Type guard

def is_safe_defaults_index(fn, i) -> bool:
    return 0 <= i < len(getattr(fn, '__defaults__', ()))

Try / catch

try:
    code = get_code_from_identifier(path)
except ValueError as e:
    raise RuntimeError(f'Default-index in {path} exceeds current signature; regenerate identifier') from e

Prevention

When it happens

Trigger: get_code_from_identifier('module.func.__defaults__[2]') where func has fewer than 3 default arguments; identifier generated when func had more defaults, then the function signature changed; off-by-one in code constructing the path.

Common situations: Signature refactoring between identifier creation and resolution; hand-written test paths indexing defaults incorrectly; stale pickled references after editing defaults.

Related errors


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

Appendix: source

Thrown at sdks/python/apache_beam/internal/code_object_pickler.py:454

    raise ValueError('Path must not be empty.')
  parts = code_object_identifier.split('.')
  if parts[0] not in sys.modules:
    raise AttributeError(f'Module {parts[0]} not found in sys.modules')
  obj = sys.modules[parts[0]]
  for part in parts[1:]:
    if name_result := _SINGLE_NAME_PATTERN.fullmatch(part):
      obj = _get_code_object_from_single_name_pattern(
          obj, name_result, code_object_identifier)
    elif lambda_with_args_result := _LAMBDA_WITH_ARGS_PATTERN.fullmatch(part):
      obj = _get_code_object_from_lambda_with_args_pattern(
          obj, lambda_with_args_result, code_object_identifier)
    elif lambda_with_hash_result := _LAMBDA_WITH_HASH_PATTERN.fullmatch(part):
      obj = _get_code_object_from_lambda_with_hash_pattern(
          obj, lambda_with_hash_result, code_object_identifier)
    elif default_result := _DEFAULT_PATTERN.fullmatch(part):
      index = int(default_result.group(2))
      if index >= len(obj.__defaults__):
        raise ValueError(
            f'Index {index} is out of bounds for obj.__defaults__'
            f' {len(obj.__defaults__)} in path {code_object_identifier}')
      obj = getattr(obj, '__defaults__')[index]
    else:
      obj = getattr(obj, part)
  if isinstance(obj, types.CodeType):
    return obj
  else:
    raise AttributeError(
        f'Could not find code object with path: {code_object_identifier}')


def _signature(obj: types.CodeType):
  """Returns the signature of a code object.

  The signature is the names of the arguments of the code object. This is used
  to unique identify lambdas.

View on GitHub (pinned to 12126d8942)