apache/beam · error · ValueError

f'test specification {identifier} must have at least one exp

Error message

f'test specification {identifier} must have at least one expected_outputs or expected_inputs'

What it means

A test specification must declare at least one expectation: either expected_outputs or expected_inputs. A test with neither would silently assert nothing, so validate_test_spec raises a ValueError identifying the test by name and line.

Source

Thrown at sdks/python/apache_beam/yaml/yaml_testing.py:155

  return spec


def validate_test_spec(test_spec):
  if not isinstance(test_spec, dict):
    raise TypeError(
        f'Test specification must be an object, got {type(test_spec)}')
  identifier = (
      test_spec.get('name', 'unknown') +
      f' at line {yaml_transform.SafeLineLoader.get_line(test_spec)}')

  if not isinstance(test_spec.get('allowed_sources', []), list):
    raise TypeError(
        f'allowed_sources of test specification {identifier} '
        f'must be a list, got {type(test_spec["allowed_sources"])}')

  if (not test_spec.get('expected_outputs', []) and
      not test_spec.get('expected_inputs', [])):
    raise ValueError(
        f'test specification {identifier} '
        f'must have at least one expected_outputs or expected_inputs')

  unknown_attrs = set(
      yaml_transform.SafeLineLoader.strip_metadata(test_spec).keys()) - set([
          'name',
          'mock_inputs',
          'mock_outputs',
          'expected_outputs',
          'expected_inputs',
          'allowed_sources',
      ])
  if unknown_attrs:
    raise ValueError(
        f'test specification {identifier} '
        f'has unknown attributes {list(unknown_attrs)}')

  for attr_type in ('mock_inputs',

View on GitHub (pinned to 12126d8942)

Solutions

  1. Add expected_outputs mapping output names to expected record lists.
  2. Add expected_inputs mapping input names to record lists if testing the input contract.
  3. Remove the test entry if it asserts nothing.

Example fix

# before
- name: my_test
  allowed_sources: [Create]

# after
- name: my_test
  allowed_sources: [Create]
  expected_outputs:
    result: [{id: 1}]
Defensive patterns

Strategy: validation

Validate before calling

if not test_spec.get('expected_outputs') and not test_spec.get('expected_inputs'):
    raise ValueError(f"test '{test_spec.get('name')}' needs expected_outputs or expected_inputs")

Type guard

def test_has_expectations(spec: dict) -> bool:
    return bool(spec.get('expected_outputs')) or bool(spec.get('expected_inputs'))

Try / catch

try:
    validate_test_spec(test_spec)
except ValueError as e:
    logging.error('Incomplete test spec: %s', e)
    raise

Prevention

When it happens

Trigger: A test entry that provides mocks or allowed_sources but omits both expected_outputs and expected_inputs (or provides them as empty values).

Common situations: Scaffolding a test and forgetting to fill in expectations, or deleting expected blocks during debugging and committing the empty test.

Understand the failure class

Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.

Related errors


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