{"record":{"id":"b8846f06f474468c","repo":"apache/beam","slug":"testing-the-truth-value-of-a-deferred-scalar-is-not-allowed","errorCode":null,"errorMessage":"Testing the truth value of a deferred scalar is not allowed. It's not possible to branch on the result of deferred operations.","messagePattern":"Testing the truth value of a deferred scalar is not allowed\\. It's not possible to branch on the result of deferred operations\\.","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"sdks/python/apache_beam/dataframe/frame_base.py","lineNumber":130,"sourceCode":"              name,\n              func, [self._expr] + [arg._expr for arg in args],\n              requires_partition_by=partitionings.Singleton()))\n\n  def __neg__(self):\n    return self.apply(operator.neg)\n\n  def __pos__(self):\n    return self.apply(operator.pos)\n\n  def __invert__(self):\n    return self.apply(operator.invert)\n\n  def __repr__(self):\n    return f\"DeferredScalar[type={type(self._expr.proxy())}]\"\n\n  def __bool__(self):\n    # TODO(BEAM-11951): Link to documentation\n    raise TypeError(\n        \"Testing the truth value of a deferred scalar is not \"\n        \"allowed. It's not possible to branch on the result of \"\n        \"deferred operations.\")\n\n\ndef _scalar_binop(op):\n  def binop(self, other):\n    if not isinstance(other, DeferredBase):\n      return self.apply(lambda left: getattr(left, op)(other), name=op)\n    elif isinstance(other, _DeferredScalar):\n      return self.apply(\n          lambda left, right: getattr(left, op)(right), name=op, args=[other])\n    else:\n      return NotImplemented\n\n  return binop\n\n","sourceCodeStart":112,"sourceCodeEnd":148,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/python/apache_beam/dataframe/frame_base.py#L112-L148","documentation":"_DeferredScalar.__bool__ deliberately raises TypeError: deferred scalars represent results computed at pipeline runtime, so their truth value is unknown at graph-construction time. Branching (if/and/or/not) on such a value would require materializing pipeline data eagerly, which the DataFrame API forbids.","triggerScenarios":"Writing `if deferred_scalar:` or using a deferred scalar in boolean context (not, and, or, assert, any condition) inside a Beam dataframe pipeline.","commonSituations":"Porting pandas code that branches on computed results; validating a computed value with `if df.max().x > 0:`; novices treating deferred objects like concrete Python values during pipeline construction.","solutions":["Restructure the pipeline to express the branch data-parallel, e.g. with filter/map and boolean column arithmetic instead of Python if.","Convert to_pcollection / to a concrete value first (materialize) and branch outside the deferred API.","Reorder so the condition is on concrete Python data known at graph-build time."],"exampleFix":"// before\nif df['x'].sum() > 0:\n  df = df.filter(...)\n// after\ndf = df[df['x'].sum() > 0]  # elementwise filter, no Python branch\n# or materialize first:\ntotal = convert.to_pcollection(df[['x']].sum(), pipeline=pipeline)","handlingStrategy":"type-guard","validationCode":"from apache_beam.dataframe.frame_base import DeferredScalar\nif isinstance(value, DeferredScalar):\n    raise TypeError('do not branch on deferred scalars; restructure with filter/map')","typeGuard":"def is_deferred_scalar(v) -> bool:\n    from apache_beam.dataframe.frame_base import DeferredScalar\n    return isinstance(v, DeferredScalar)","tryCatchPattern":null,"preventionTips":["Treat every value derived from a deferred dataframe as graph-time opaque; never use it in if/and/or.","Express conditionals as boolean column arithmetic and df[bool_expr] filtering.","Materialize (to_pcollection + run) when you truly need a Python-level branch."],"tags":["python","apache-beam","dataframe-api","deferred"],"backgroundTag":"unsupported-operation","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"}