{"record":{"id":"c433f9f5a6562645","repo":"apache/beam","slug":"should-never-be-expanded-directly","errorCode":null,"errorMessage":"Should never be expanded directly.","messagePattern":"Should never be expanded directly\\.","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"sdks/python/apache_beam/transforms/ptransform.py","lineNumber":1187,"sourceCode":"    return fn.default_label()\n  elif hasattr(fn, '__name__'):\n    if fn.__name__ == '<lambda>':\n      return '<lambda at %s:%s>' % (\n          os.path.basename(fn.__code__.co_filename), fn.__code__.co_firstlineno)\n    return fn.__name__\n  return str(fn)\n\n\nclass _NamedPTransform(PTransform):\n  def __init__(self, transform, label):\n    super().__init__(label)\n    self.transform = transform\n\n  def __ror__(self, pvalueish, _unused=None):\n    return self.transform.__ror__(pvalueish, self.label)\n\n  def expand(self, pvalue):\n    raise RuntimeError(\"Should never be expanded directly.\")\n\n  def annotations(self):\n    return self.transform.annotations()\n\n  def __rrshift__(self, label):\n    return _NamedPTransform(self.transform, label)\n\n  def with_resource_hints(self, **kwargs):\n    self.transform.with_resource_hints(**kwargs)\n    return self\n\n  def __getattr__(self, attr):\n    transform_attr = getattr(self.transform, attr)\n    if callable(transform_attr):\n\n      @wraps(transform_attr)\n      def wrapper(*args, **kwargs):\n        result = transform_attr(*args, **kwargs)","sourceCodeStart":1169,"sourceCodeEnd":1205,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/python/apache_beam/transforms/ptransform.py#L1169-L1205","documentation":"`_NamedPTransform` (used to attach labels, e.g. `'label' >> transform`) is only a wrapper delegating to an inner transform; it has no expansion of its own. Calling expand() on it directly is a programming error, so it raises RuntimeError('Should never be expanded directly.').","triggerScenarios":"Calling `.expand(pvalue)` on a `_NamedPTransform` (i.e., a transform obtained from the `>>` label operator), or code that walks the transform graph and calls expand on wrapper nodes.","commonSituations":"Custom pipeline introspection/traversal code that mistakenly expands labeled wrappers; misuse of internal Beam APIs in testing or framework glue.","solutions":["Expand the inner transform instead: use `wrapper.transform.expand(pvalue)`.","Apply the labeled transform through `|` / `__ror__` (e.g. `pcollection | 'name' >> MyTransform()`), never by calling expand manually.","In graph-traversal code, unwrap `_NamedPTransform` nodes via their `transform` attribute before expanding."],"exampleFix":"# before\n('label' >> beam.Map(fn)).expand(pc)\n# after\npc | 'label' >> beam.Map(fn)\n# or: ('label' >> beam.Map(fn)).transform.expand(pc)","handlingStrategy":"type-guard","validationCode":"from apache_beam.transforms.ptransform import _NamedPTransform\nif isinstance(t, _NamedPTransform):\n  t = t.transform","typeGuard":"def unwrap_transform(t):\n  from apache_beam.transforms.ptransform import _NamedPTransform\n  return t.transform if isinstance(t, _NamedPTransform) else t","tryCatchPattern":"try:\n  out = t.expand(pc)\nexcept RuntimeError as e:\n  if 'Should never be expanded directly' in str(e):\n    t = unwrap_transform(t)\n    out = t.expand(pc)\n  else:\n    raise","preventionTips":["Never call expand() directly in user code; apply transforms with `|`.","In traversal code, always unwrap _NamedPTransform wrappers via .transform.","Prefer the public pipeline API over internal Beam classes."],"tags":["python","apache-beam","internal-api"],"backgroundTag":"unsupported-operation","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"}