apache/beam · error · NotImplementedError

does not properly override _extract_input_pvalues, returned…

Error message

%s does not properly override _extract_input_pvalues, returned %s from %s

What it means

After _extract_input_pvalues returns, Beam validates that every key is a str and every value is a PValue. A transform whose override returns anything else (wrong types, wrong container) triggers this NotImplementedError naming the transform, returned inputs, and original pvalueish.

Solutions

  1. Fix _extract_input_pvalues to return (pvalueish, {str_key: PValue_leaf, ...}).
  2. Convert keys with str(...) and ensure every value is a PCollection/PValue instance.
  3. Flatten nested containers into leaf PValues.
  4. Check upstream for how the base PTransform implementation does it and mirror the contract.

Example fix

// before
def _extract_input_pvalues(self, pvalueish):
  return pvalueish, {0: pvalueish[0], 1: 'not a pvalue'}
// after
def _extract_input_pvalues(self, pvalueish):
  return pvalueish, {'a': pvalueish[0], 'b': pvalueish[1]}
Defensive patterns

Strategy: validation

Validate before calling

from apache_beam.pvalue import PValue
def check_extract_result(inputs):
    assert isinstance(inputs, dict), 'inputs must be dict'
    for k, v in inputs.items():
        assert isinstance(k, str) and isinstance(v, PValue), f'bad entry {k!r}: {type(v)}'

Try / catch

try:
    out = pipeline.apply(t, pvalueish)
except NotImplementedError as e:
    if 'properly override _extract_input_pvalues' in str(e):
        raise ValueError(f'fix {t}._extract_input_pvalues return contract') from e

Prevention

When it happens

Trigger: A custom PTransform overrides _extract_input_pvalues but returns non-string keys (e.g. int keys) or non-PValue leaves (raw data, None, nested lists) in the inputs mapping.

Common situations: Hand-written composite transforms with partial/incorrect _extract_input_pvalues implementations; returning the pvalueish itself when it contains non-PValue members; SDK changes tightening validation on previously-tolerated returns.

Related errors


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

Appendix: source

Thrown at sdks/python/apache_beam/pipeline.py:785

    if pvalueish is None:
      full_label = self._current_transform().full_label
      raise TypeCheckError(
          f'Transform "{full_label}" was applied to the output of '
          f'an object of type None.')

    pvalueish, inputs = transform._extract_input_pvalues(pvalueish)
    try:
      if not isinstance(inputs, dict):
        inputs = {str(ix): input for (ix, input) in enumerate(inputs)}
    except TypeError:
      raise NotImplementedError(
          'Unable to extract PValue inputs from %s; either %s does not accept '
          'inputs of this format, or it does not properly override '
          '_extract_input_pvalues' % (pvalueish, transform))
    for t, leaf_input in inputs.items():
      if not isinstance(leaf_input, pvalue.PValue) or not isinstance(t, str):
        raise NotImplementedError(
            '%s does not properly override _extract_input_pvalues, '
            'returned %s from %s' % (transform, inputs, pvalueish))

    current = AppliedPTransform(
        self._current_transform(),
        transform,
        full_label,
        inputs,
        None,
        annotations=self._current_annotations())
    self._current_transform().add_part(current)

    try:
      self.transforms_stack.append(current)

      type_options = self._options.view_as(TypeOptions)
      if type_options.pipeline_type_check:
        transform.type_check_inputs(pvalueish)

View on GitHub (pinned to 12126d8942)