apache/beam · error · ValueError
At least one of --render_port or --render_output must be pro
Error message
At least one of --render_port or --render_output must be provided.
What it means
The graphviz renderer requires at least one output channel: an HTTP render port or output files. run_portable_pipeline raises ValueError when --render_port is negative (disabled) and --render_output is empty. It is an early option-validation guard before rendering begins.
Source
Thrown at sdks/python/apache_beam/runners/render.py:408
{cmapx}
</div>
</body>
</html>
"""
class RenderRunner(runner.PipelineRunner):
# TODO(robertwb): Consider making this a runner wrapper, where live status
# (such as counters, stage completion status, or possibly even PCollection
# samples) queryable and/or displayed. This could evolve into a full Beam
# UI.
def run_pipeline(self, pipeline_object, options):
return self.run_portable_pipeline(pipeline_object.to_runner_api(), options)
def run_portable_pipeline(self, pipeline_proto, options):
render_options = options.view_as(RenderOptions)
if render_options.render_port < 0 and not render_options.render_output:
raise ValueError(
'At least one of --render_port or --render_output must be provided.')
if render_options.log_proto:
_LOGGER.info(pipeline_proto)
renderer = PipelineRenderer(pipeline_proto, render_options)
try:
subprocess.run(['dot', '-V'], capture_output=True, check=True)
except FileNotFoundError as exn:
# If dot is not available, we can at least output the raw .dot files.
dot_files = [
output for output in render_options.render_output
if output.endswith('.dot')
]
for output in dot_files:
with open(output, 'w') as fout:
fout.write(renderer.to_dot())
_LOGGER.info("Wrote pipeline as %s", output)
non_dot_files = set(render_options.render_output) - set(dot_files)View on GitHub (pinned to 12126d8942)
Solutions
- Pass --render_output=path.dot (or multiple outputs) when launching the render runner
- Set a valid --render_port (>= 0), e.g. --render_port 8099, to serve the graph over HTTP
- Provide both if you want file and HTTP output
Example fix
# before python -m apache_beam.runners.render --pipeline_file=pipeline.pb # ValueError # after python -m apache_beam.runners.render --pipeline_file=pipeline.pb --render_output=pipeline.dot
Defensive patterns
Strategy: validation
Validate before calling
from apache_beam.options.pipeline_options import PipelineOptions
opts = PipelineOptions(argv)
r = opts.view_as(RenderOptionsLike)
if r.render_port < 0 and not r.render_output:
raise SystemExit('Provide --render_port >= 0 or --render_output=FILE.dot') Type guard
def render_target_configured(render_port: int, render_output) -> bool:
return render_port >= 0 or bool(render_output) Try / catch
try:
result = pipeline.run()
except ValueError as e:
if 'render_port or --render_output' in str(e):
argv += ['--render_output', 'pipeline.dot']
result = PipelineOptions(argv).run_pipeline(...)
else:
raise Prevention
- Always pass --render_output or --render_port when invoking the render runner
- Default render flags in wrapper scripts for the render entry point
- Add a smoke test that renders a trivial pipeline with your standard flags
When it happens
Trigger: Invoking the render runner (e.g. --runner=RenderRunner or beam render CLI) without setting --render_output and with --render_port left at its disabled default (<0), or explicitly passing --render_port=-1.
Common situations: Running 'python -m apache_beam.runners.render' with no output flags; forgetting --render_port 8099 when expecting a web view; scripts that clear render_output while disabling the port.
Understand the failure class
Background: "Must pass :limit option" / "Missing required option" — required option errors explained — this error's family across 41 libraries.
Related errors
- MatchContinuously interval must be positive.
- Invalid create disposition %s. Expecting %s
- Invalid write disposition %s. Expecting %s
- Invalid schema update option %s. Expecting %s
- change_function must be 'CHANGES' or 'APPENDS', got '{change
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/ffef33a3bec5f844.
Report an issue: GitHub.