{"record":{"id":"891a601063ba78ba","repo":"apache/beam","slug":"either-a-read-artifact-location-or-write-artifact-location","errorCode":null,"errorMessage":"Either a read_artifact_location or write_artifact_location must be specified to initialize MLTransform","messagePattern":"Either a read_artifact_location or write_artifact_location must be specified to initialize MLTransform","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"sdks/python/apache_beam/ml/transforms/base.py","lineNumber":360,"sourceCode":"        applied to the dataset and generated values like min, max from\n        ScaleTo01, and mean, var from ScaleToZScore. Note that when consuming\n        artifacts, it is not necessary to pass the transforms since they are\n        inherently stored within the artifacts themselves. The value assigned\n        to `read_artifact_location` should be a valid storage path where the\n        artifacts can be read from. Only one of write_artifact_location and\n        read_artifact_location should be specified.\n      transforms: A list of transforms to apply to the data. All the transforms\n        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","sourceCodeStart":342,"sourceCodeEnd":378,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/python/apache_beam/ml/transforms/base.py#L342-L378","documentation":"MLTransform requires at least one artifact location: either write_artifact_location (produce mode, persisting transform artifacts) or read_artifact_location (consume mode, loading previously written artifacts). With neither set, initialization fails with this ValueError.","triggerScenarios":"Calling MLTransform(transforms=[...]) with no artifact_location arguments at all.","commonSituations":"Omitting artifact_location when following quickstart snippets that abbreviated the API; constructing MLTransform programmatically and forgetting the location parameter.","solutions":["Add write_artifact_location=<path> when applying transforms for the first time.","Use read_artifact_location=<path> to reuse artifacts from a prior MLTransform run.","Ensure the path is accessible to the pipeline (local path for DirectRunner, GCS/DFS path for distributed runners)."],"exampleFix":"// before\nMLTransform(transforms=[MLTransformsWrapper(...)])\n// after\nMLTransform(write_artifact_location='gs://bucket/artifacts', transforms=[MLTransformsWrapper(...)])","handlingStrategy":"validation","validationCode":"def make_mltransform(**kw):\n    if not kw.get('read_artifact_location') and not kw.get('write_artifact_location'):\n        raise ValueError('artifact location required')\n    return MLTransform(**kw)","typeGuard":"def artifact_location_present(cfg) -> bool:\n    return bool(cfg.get('read_artifact_location') or cfg.get('write_artifact_location'))","tryCatchPattern":"try:\n    t = MLTransform(transforms=ts)\nexcept ValueError as e:\n    if 'must be specified' in str(e):\n        t = MLTransform(write_artifact_location='gs://bucket/artifacts', transforms=ts)\n    else:\n        raise","preventionTips":["Make artifact_location a mandatory parameter of your pipeline-config layer","Use versioned artifact paths (gs://bucket/artifacts/v1)","Verify runner access to the artifact path before launching"],"tags":["python","apache-beam","configuration"],"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-20T03:17:13.778Z"}