{"record":{"id":"20fc7639ec999aff","repo":"apache/beam","slug":"unexpected-phase-s","errorCode":null,"errorMessage":"Unexpected phase: %s","messagePattern":"Unexpected phase: (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"sdks/python/apache_beam/transforms/combiners.py","lineNumber":962,"sourceCode":"\nclass PhasedCombineFnExecutor(object):\n  \"\"\"Executor for phases of combine operations.\"\"\"\n  def __init__(self, phase, fn, args, kwargs):\n\n    self.combine_fn = curry_combine_fn(fn, args, kwargs)\n\n    if phase == 'all':\n      self.apply = self.full_combine\n    elif phase == 'add':\n      self.apply = self.add_only\n    elif phase == 'merge':\n      self.apply = self.merge_only\n    elif phase == 'extract':\n      self.apply = self.extract_only\n    elif phase == 'convert':\n      self.apply = self.convert_to_accumulator\n    else:\n      raise ValueError('Unexpected phase: %s' % phase)\n\n  def full_combine(self, elements):\n    return self.combine_fn.apply(elements)\n\n  def add_only(self, elements):\n    return self.combine_fn.add_inputs(\n        self.combine_fn.create_accumulator(), elements)\n\n  def merge_only(self, accumulators):\n    return self.combine_fn.merge_accumulators(accumulators)\n\n  def extract_only(self, accumulator):\n    return self.combine_fn.extract_output(accumulator)\n\n  def convert_to_accumulator(self, element):\n    return self.combine_fn.add_input(\n        self.combine_fn.create_accumulator(), element)\n","sourceCodeStart":944,"sourceCodeEnd":980,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/python/apache_beam/transforms/combiners.py#L944-L980","documentation":"ValueError raised when constructing a phased combiner wrapper (a helper whose `apply` is selected per phase) with a phase string other than 'add', 'merge', 'extract', or 'convert'. The phase dispatch has no branch for the given value, so Beam treats it as an invalid phase.","triggerScenarios":"Constructing the phase-selecting combiner object with `phase='sum'`, `'all'`, a typo like `'adds'`, or an empty/None phase string.","commonSituations":"Typos in phase names; iterating a config list containing an unsupported phase; confusion over which phases the wrapper supports (add/merge/extract/convert only).","solutions":["Use one of the supported phase strings: 'add', 'merge', 'extract', or 'convert'.","If the phase comes from config, validate it against the allowed set before constructing.","Check spelling/case of the phase value."],"exampleFix":"// before\nPhasedCombineFn(..., phase='combine')  # invalid\n// after\nPhasedCombineFn(..., phase='add')  # one of add|merge|extract|convert","handlingStrategy":"validation","validationCode":"VALID_PHASES = {'add', 'merge', 'extract', 'convert'}\nif phase not in VALID_PHASES:\n    raise ValueError(f'phase must be one of {sorted(VALID_PHASES)}, got {phase!r}')","typeGuard":"from typing import Literal\ndef is_valid_phase(p: str) -> bool:\n    return p in ('add', 'merge', 'extract', 'convert')","tryCatchPattern":null,"preventionTips":["Use Literal['add','merge','extract','convert'] typing for phase params","Validate config-driven phase strings at load time","Check spelling against the supported phase set"],"tags":["apache-beam","combiners","invalid-value"],"backgroundTag":"invalid-enum-value","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-20T03:17:13.778Z"}