{"record":{"id":"e891893f0ed87f7e","repo":"apache/beam","slug":"transforms-should-not-be-passed-in-read-mode-in-read-mode","errorCode":null,"errorMessage":"Transforms should not be passed in read mode. In read mode, the transforms are read from the artifact location.","messagePattern":"Transforms should not be passed in read mode\\. In read mode, the transforms are read from the artifact location\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"sdks/python/apache_beam/ml/transforms/base.py","lineNumber":368,"sourceCode":"        are applied in the order they are specified. The input of the\n        i-th transform is the output of the (i-1)-th transform. Multi-input\n        transforms are not supported yet.\n    \"\"\"\n    if read_artifact_location and write_artifact_location:\n      raise ValueError(\n          'Only one of read_artifact_location or write_artifact_location can '\n          'be specified to initialize MLTransform')\n\n    if not read_artifact_location and not write_artifact_location:\n      raise ValueError(\n          'Either a read_artifact_location or write_artifact_location must be '\n          'specified to initialize MLTransform')\n\n    if read_artifact_location:\n      artifact_location = read_artifact_location\n      artifact_mode = ArtifactMode.CONSUME\n      if transforms:\n        raise ValueError(\n            'Transforms should not be passed in read mode. In read mode, '\n            'the transforms are read from the artifact location.')\n\n    else:\n      artifact_location = write_artifact_location  # type: ignore[assignment]\n      artifact_mode = ArtifactMode.PRODUCE\n\n    self._parent_artifact_location = artifact_location\n\n    self._artifact_mode = artifact_mode\n    self.transforms = transforms or []\n    self._counter = Metrics.counter(\n        MLTransform, f'BeamML_{self.__class__.__name__}')\n    self._with_exception_handling = False\n    self._exception_handling_args: dict[str, Any] = {}\n\n  def expand(\n      self, pcoll: beam.PCollection[ExampleT]","sourceCodeStart":350,"sourceCodeEnd":386,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/python/apache_beam/ml/transforms/base.py#L350-L386","documentation":"MLTransform.__init__ rejects passing transform objects when read_artifact_location is set: in read mode the transform chain must be reconstructed from the previously written artifact, and caller-supplied transforms would silently not be used.","triggerScenarios":"MLTransform(read_artifact_location=path, transforms=[...]) — supplying transforms together with read_artifact_location.","commonSituations":"Reusing a write-mode MLTransform constructor and only swapping write_artifact_location to read_artifact_location without removing the transforms list; templated pipelines that always pass transforms.","solutions":["Remove the transforms argument when using read_artifact_location.","If you need to re-run with transforms, use write_artifact_location (PRODUCE mode) instead.","Keep separate pipeline code paths (or a flag) for produce vs consume modes."],"exampleFix":"// before\nMLTransform(read_artifact_location=loc, transforms=[Embedding(...)])\n// after\nMLTransform(read_artifact_location=loc)","handlingStrategy":"validation","validationCode":"def make_mltransform(**kw):\n    if kw.get('read_artifact_location') and kw.get('transforms'):\n        raise ValueError('Do not pass transforms in read mode')\n    return MLTransform(**kw)","typeGuard":"def read_mode_config_ok(read_loc, transforms) -> bool:\n    return not (read_loc and transforms)","tryCatchPattern":"try:\n    t = MLTransform(read_artifact_location=loc, transforms=ts)\nexcept ValueError as e:\n    if 'read mode' in str(e):\n        t = MLTransform(read_artifact_location=loc)\n    else:\n        raise","preventionTips":["Separate produce and consume pipeline templates so read mode never receives transforms","Strip transforms automatically when read_artifact_location is set","Add a code-review checklist item for MLTransform mode switching"],"tags":["python","apache-beam","configuration"],"backgroundTag":"mutually-exclusive-options","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"}