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
- Verify len(func.__defaults__) covers the index: `assert i < len(f.__defaults__)` before calling.
- Regenerate the identifier after any change to the function's default arguments.
- Fix the index in the path (0-based) if it was constructed incorrectly.
- 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
- Regenerate identifiers after changing function signatures/default arguments.
- Compute indices from len(f.__defaults__) rather than hardcoding.
- Add a unit test resolving serialized identifiers against current source.
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
- can't (safely) pickle generator objects
- cannot check importability of
- Could not find code object with path
- Could not find code object with path
- Invalid pattern for single name
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)