{"record":{"id":"7be28fbe04e84cd2","repo":"apache/beam","slug":"stage-s-has-no-main-inputs-at-least-one-main-input-is","errorCode":null,"errorMessage":"Stage %s has no main inputs. At least one main input is necessary.","messagePattern":"Stage (.+?) has no main inputs\\. At least one main input is necessary\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"sdks/python/apache_beam/runners/portability/fn_api_runner/watermark_manager.py","lineNumber":184,"sourceCode":"\n      # 4. Get stage side inputs, create nodes for them, add to\n      #    _pcollections_by_name, and add them as side inputs of the stage.\n      for pcoll_name in s.side_inputs():\n        if pcoll_name not in self._pcollections_by_name:\n          self._pcollections_by_name[\n              pcoll_name] = WatermarkManager.PCollectionNode(pcoll_name)\n        pcoll_node = self._pcollections_by_name[pcoll_name]\n        assert isinstance(pcoll_node, WatermarkManager.PCollectionNode)\n        stage_node.side_inputs.add(pcoll_node)\n\n    self._verify(stages)\n\n  def _verify(self, stages: list[translations.Stage]):\n    for s in stages:\n      if len(self._stages_by_name[s.name].inputs) == 0:\n        from apache_beam.runners.portability.fn_api_runner import visualization_tools\n        visualization_tools.show_stage(s)\n        raise ValueError(\n            'Stage %s has no main inputs. '\n            'At least one main input is necessary.' % s.name)\n\n  def get_stage_node(self, name: str) -> StageNode:\n    # noqa: F821\n    return self._stages_by_name[name]\n\n  def get_pcoll_node(self, name: str) -> PCollectionNode:\n    # noqa: F821\n    return self._pcollections_by_name[name]\n\n  def set_pcoll_watermark(self, name, watermark):\n    element = self._pcollections_by_name[name]\n    element.set_watermark(watermark)\n","sourceCodeStart":166,"sourceCodeEnd":199,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/python/apache_beam/runners/portability/fn_api_runner/watermark_manager.py#L166-L199","documentation":"The Fn API runner's watermark manager requires every execution stage to have at least one main input so watermarks can propagate; `_verify` (called from __init__) raises ValueError when a stage has zero main inputs. It dumps the offending stage via visualization_tools before raising to aid debugging.","triggerScenarios":"Building a WatermarkManager over a set of translations.Stage objects where some stage's `inputs` dict is empty — e.g. a graph-transformation step produced an isolated stage or incorrectly dropped its input PCollections.","commonSituations":"Graph rewriting bugs in fn_api_runner translations; a stage whose only inputs were consumed as side inputs or removed by an optimization; misconfigured pipeline during portability work.","solutions":["Inspect the printed stage (visualization_tools.show_stage) to see why its inputs were dropped","Check recent custom transforms/translations that may create stages without main inputs","File/check a Beam issue: this usually indicates a runner-side graph-construction bug, not user error","Work around by restructuring the pipeline so the stage has a real main input PCollection"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"for stage in stages:\n  if not stage.inputs:\n    raise ValueError(f'Stage {stage.name} has no main inputs; fix graph construction before WatermarkManager init')","typeGuard":"def has_main_inputs(stage):\n  return bool(stage.inputs)","tryCatchPattern":null,"preventionTips":["Never create translations.Stage objects without at least one main input PCollection","Run pipeline-graph validation/visualization before runner execution","Keep custom translations in sync with upstream Beam graph rewrites"],"tags":["python","apache-beam","watermark","pipeline-graph"],"backgroundTag":"invalid-state-transition","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"}