{"record":{"id":"82a19a4231f63204","repo":"apache/beam","slug":"stdout-file-must-be-specified-with-background","errorCode":null,"errorMessage":"--stdout_file must be specified with --background","messagePattern":"--stdout_file must be specified with --background","errorType":"validation","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"sdks/python/apache_beam/runners/portability/local_job_service_main.py","lineNumber":107,"sourceCode":"      os.unlink(options.pid_file)\n    else:\n      print('Process id file', options.pid_file, 'already removed.')\n    if not options.background:\n      return\n\n  if options.background:\n    if not options.pid_file:\n      raise RuntimeError('--pid_file must be specified with --start')\n    if options.stop:\n      argv.remove('--stop')\n    argv.remove('--background')\n    if not options.port_file:\n      options.port_file = os.path.splitext(options.pid_file)[0] + '.port'\n      argv.append('--port_file')\n      argv.append(options.port_file)\n\n    if not options.stdout_file:\n      raise RuntimeError('--stdout_file must be specified with --background')\n    os.makedirs(pathlib.PurePath(options.stdout_file).parent, exist_ok=True)\n    stdout_dest = open(options.stdout_file, mode='w')\n\n    if options.stderr_file:\n      os.makedirs(pathlib.PurePath(options.stderr_file).parent, exist_ok=True)\n      stderr_dest = open(options.stderr_file, mode='w')\n    else:\n      stderr_dest = subprocess.STDOUT\n\n    subprocess.Popen([\n        sys.executable,\n        '-m',\n        'apache_beam.runners.portability.local_job_service_main'\n    ] + argv,\n                     stderr=stderr_dest,\n                     stdout=stdout_dest)\n    print('Waiting for server to start up...')\n    while not os.path.exists(options.port_file):","sourceCodeStart":89,"sourceCodeEnd":125,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/python/apache_beam/runners/portability/local_job_service_main.py#L89-L125","documentation":"When the job service is launched with --background, run() requires --stdout_file so the daemon's output is redirected to a real file (the parent directory is created with os.makedirs). Without it there is nowhere to send the backgrounded process's stdout, so a RuntimeError is raised.","triggerScenarios":"Starting the local job service with --background (e.g. as part of --start) while omitting --stdout_file.","commonSituations":"Daemonizing the service for pytest/CI setups where only pid and port files were configured; forgetting that --background (implied by --start) also needs a stdout destination.","solutions":["Pass --stdout_file /path/to/service.log with --background.","Optionally also pass --stderr_file to capture stderr (it is optional but recommended).","Run without --background to keep output on the terminal."],"exampleFix":"// before\npython -m apache_beam.runners.portability.local_job_service_main --start --pid_file /tmp/svc.pid\n// after\npython -m apache_beam.runners.portability.local_job_service_main --start --pid_file /tmp/svc.pid --stdout_file /tmp/svc.log --stderr_file /tmp/svc.err","handlingStrategy":"validation","validationCode":"required = {'--pid_file', '--stdout_file'}\nmissing = [f for f in required if not any(a.startswith(f) for a in cli_args)]\nassert not missing, f'missing flags for --background: {missing}'","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Keep a single launch wrapper that always supplies pid_file, stdout_file and stderr_file together.","Ensure the stdout_file parent directory is writable so os.makedirs succeeds.","Avoid hand-typing daemonization flags; script them."],"tags":["cli","missing-flag","daemonization"],"backgroundTag":"missing-required-flag","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-14T21:17:11.552Z"}