{"record":{"id":"84ccefd77e9a10bb","repo":"apache/beam","slug":"could-not-translate-the-internal-step-name-r-since-job-graph","errorCode":null,"errorMessage":"Could not translate the internal step name %r since job graph is not available.","messagePattern":"Could not translate the internal step name %r since job graph is not available\\.","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"warning","filePath":"sdks/python/apache_beam/runners/dataflow/dataflow_metrics.py","lineNumber":99,"sourceCode":"    self._cached_metrics = None\n    self._job_graph = job_graph\n\n  @staticmethod\n  def _is_counter(metric_result):\n    return isinstance(metric_result.attempted, numbers.Number)\n\n  @staticmethod\n  def _is_distribution(metric_result):\n    return isinstance(metric_result.attempted, DistributionResult)\n\n  @staticmethod\n  def _is_string_set(metric_result):\n    return isinstance(metric_result.attempted, set)\n\n  def _translate_step_name(self, internal_name):\n    \"\"\"Translate between internal step names (e.g. \"s1\") and user step names.\"\"\"\n    if not self._job_graph:\n      raise ValueError(\n          'Could not translate the internal step name %r since job graph is '\n          'not available.' % internal_name)\n    user_step_name = None\n    if (self._job_graph and internal_name\n        in self._job_graph.proto_pipeline.components.transforms.keys()):\n      # Dataflow Portable Runner with portable job submission uses proto transform map\n      # IDs for step names. Also PTransform.unique_name maps to user step names.\n      # Hence we lookup user step names based on the proto.\n      user_step_name = self._job_graph.proto_pipeline.components.transforms[\n          internal_name].unique_name\n    else:\n      try:\n        step = _get_match(\n            self._job_graph.proto.steps, lambda x: x.name == internal_name)\n        user_step_name = step.properties.get('user_name')\n      except ValueError:\n        pass  # Exception is handled below.\n    if not user_step_name:","sourceCodeStart":81,"sourceCodeEnd":117,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/python/apache_beam/runners/dataflow/dataflow_metrics.py#L81-L117","documentation":"DataflowMetrics translates internal Dataflow step names (like 's1') to user-facing names using the job graph; if the graph was not provided (self._job_graph is falsy), translation is impossible and it raises ValueError.","triggerScenarios":"Creating a DataflowMetrics/query object without a job_graph and then querying metrics whose step names need translation — e.g. DataflowMetrics(job_result, dataflow_client) with no graph arg, then reading metric keys.","commonSituations":"Using the Dataflow metrics API programmatically (google.cloud.dataflow client) without passing the job graph retrieved at submission time.","solutions":["Pass the job graph when constructing the metrics helper (DataflowMetrics(..., job_graph)).","Fetch the job graph from the Dataflow API before querying if it wasn't retained.","Accept internal step names in results if translation is unavailable (catch ValueError and use the raw name)."],"exampleFix":"# before\nmetrics = DataflowMetrics(job_result, dataflow_client)  # no graph\n# after\nmetrics = DataflowMetrics(job_result, dataflow_client, job_graph=job_graph)","handlingStrategy":"validation","validationCode":"if metrics._job_graph is None:\n    raise RuntimeError('Provide job_graph to DataflowMetrics for step-name translation')","typeGuard":"def has_job_graph(metrics) -> bool:\n    return getattr(metrics, '_job_graph', None) is not None","tryCatchPattern":"try:\n    name = metrics._translate_step_name(internal)\nexcept ValueError as e:\n    if 'job graph is not available' in str(e):\n        name = internal\n    else:\n        raise","preventionTips":["Always pass the job graph when constructing DataflowMetrics.","Persist the job graph alongside the job result for later queries.","Fall back to raw internal names when translation is unavailable."],"tags":["python","apache-beam","dataflow","metrics","missing-context"],"backgroundTag":"missing-required-argument","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}