{"record":{"id":"0d6034af2bf4b885","repo":"apache/beam","slug":"failed-to-cancel-job-s-please-go-to-the-developers-console","errorCode":null,"errorMessage":"Failed to cancel job %s, please go to the Developers Console to cancel it manually.","messagePattern":"Failed to cancel job (.+?), please go to the Developers Console to cancel it manually\\.","errorType":"exception","errorClass":"DataflowRuntimeException","httpStatus":null,"severity":"error","filePath":"sdks/python/apache_beam/runners/dataflow/dataflow_runner.py","lineNumber":865,"sourceCode":"  def cancel(self):\n    if not self.has_job:\n      raise IOError('Failed to get the Dataflow job id.')\n\n    self._update_job()\n\n    if self.is_in_terminal_state():\n      _LOGGER.warning(\n          'Cancel failed because job %s is already terminated in state %s.',\n          self.job_id(),\n          self.state)\n    else:\n      if not self._runner.dataflow_client.modify_job_state(\n          self.job_id(), 'JOB_STATE_CANCELLED'):\n        cancel_failed_message = (\n            'Failed to cancel job %s, please go to the Developers Console to '\n            'cancel it manually.') % self.job_id()\n        _LOGGER.error(cancel_failed_message)\n        raise DataflowRuntimeException(cancel_failed_message, self)\n\n    return self.state\n\n  def __str__(self):\n    return '<%s %s %s>' % (self.__class__.__name__, self.job_id(), self.state)\n\n  def __repr__(self):\n    return '<%s %s at %s>' % (self.__class__.__name__, self._job, hex(id(self)))\n\n\nclass DataflowRuntimeException(Exception):\n  \"\"\"Indicates an error has occurred in running this pipeline.\"\"\"\n  def __init__(self, msg, result):\n    super().__init__(msg)\n    self.result = result\n","sourceCodeStart":847,"sourceCodeEnd":881,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/python/apache_beam/runners/dataflow/dataflow_runner.py#L847-L881","documentation":"DataflowRuntimeException raised by cancel() when the Dataflow service's modify_job_state() call fails to move the job to JOB_STATE_CANCELLED (returns falsy). The error tells the user to cancel the job manually in the Developers Console.","triggerScenarios":"Calling pipeline_result.cancel() while the Dataflow API accepts but does not apply the cancellation — e.g. the job already finished between the terminal-state check and the modify call, transient API errors, or insufficient permissions on the job.","commonSituations":"Race conditions where the job completes just as cancel() is called; IAM principals lacking dataflow.jobs.updateInstanceState permission; service hiccups.","solutions":["Open the job in the GCP Developers Console and cancel it manually as the message instructs","Retry cancel(); if the job already terminated the is_in_terminal_state() check will short-circuit with a warning","Verify the caller's IAM permissions include dataflow.jobs.updateInstanceState on the project"],"exampleFix":"# before\nresult.cancel()\n# after\ntry:\n    result.cancel()\nexcept DataflowRuntimeException as e:\n    print('Manual cancellation required:', e)","handlingStrategy":"retry","validationCode":"# pre-check permissions\n# gcloud projects get-iam-policy PROJECT --format=json | grep dataflow","typeGuard":null,"tryCatchPattern":"for attempt in range(3):\n    try:\n        result.cancel()\n        break\n    except DataflowRuntimeException:\n        time.sleep(2 ** attempt)\nelse:\n    print('Cancel via console/API manually')","preventionTips":["Grant the calling principal dataflow.jobs.updateInstanceState permission","Handle the race where the job finishes during cancel — check is_in_terminal_state first","Have an operational fallback (console or API-based cancel) documented"],"tags":["dataflow","gcp","cancel","permissions"],"backgroundTag":"api-error-response","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"}