{"record":{"id":"06d3f3ff6fa3cfeb","repo":"apache/beam","slug":"either-columns-or-type-adapter-must-be-specified","errorCode":null,"errorMessage":"Either columns or type_adapter must be specified","messagePattern":"Either columns or type_adapter must be specified","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"sdks/python/apache_beam/ml/transforms/base.py","lineNumber":281,"sourceCode":"      columns: Optional[list[str]] = None,\n      type_adapter: Optional[EmbeddingTypeAdapter] = None,\n      # common args for all ModelHandlers.\n      load_model_args: Optional[dict[str, Any]] = None,\n      min_batch_size: Optional[int] = None,\n      max_batch_size: Optional[int] = None,\n      large_model: bool = False,\n      **kwargs):\n    self.load_model_args = load_model_args or {}\n    self.min_batch_size = min_batch_size\n    self.max_batch_size = max_batch_size\n    self.large_model = large_model\n    self.columns = columns\n    if columns is not None:\n      self.type_adapter = _create_dict_adapter(columns)\n    elif type_adapter is not None:\n      self.type_adapter = type_adapter\n    else:\n      raise ValueError(\"Either columns or type_adapter must be specified\")\n    self.inference_args = kwargs.pop('inference_args', {})\n\n    if kwargs:\n      _LOGGER.warning(\"Ignoring the following arguments: %s\", kwargs.keys())\n\n  # TODO:https://github.com/apache/beam/pull/29564 add set_model_handler method\n  @abc.abstractmethod\n  def get_model_handler(self) -> ModelHandler:\n    \"\"\"\n    Return framework specific model handler.\n    \"\"\"\n\n  def get_columns_to_apply(self):\n    return self.columns\n\n\nclass MLTransform(\n    beam.PTransform[beam.PCollection[ExampleT],","sourceCodeStart":263,"sourceCodeEnd":299,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/python/apache_beam/ml/transforms/base.py#L263-L299","documentation":"MLTransform's setup requires either a columns specification (used to build a dict adapter) or an explicit type_adapter; with neither, it cannot convert pipeline elements into the dict form transforms need, so a ValueError is raised.","triggerScenarios":"Constructing MLTransform (or a transform's with_transform configuration) without passing columns and without providing type_adapter.","commonSituations":"Copy-pasting MLTransform setup where the columns kwarg was accidentally deleted; custom transforms passing a model handler but forgetting input configuration.","solutions":["Pass columns=[...] to the transform configuration listing the dict keys to extract.","Alternatively supply a custom type_adapter implementing the expected conversion.","Check the MLTransform docs example for the with_transform(columns=...) pattern."],"exampleFix":"// before\nMLTransform(write_artifact_location=loc).with_transform(ImageEmbedding(model_name='resnet'))\n// after\nMLTransform(write_artifact_location=loc).with_transform(ImageEmbedding(model_name='resnet', columns=['image_bytes']))","handlingStrategy":"validation","validationCode":"def build_mltransform(transforms, columns=None, type_adapter=None, **kw):\n    if columns is None and type_adapter is None:\n        raise ValueError('Pass columns or type_adapter')\n    return MLTransform(**kw).with_transform(transforms(columns=columns)) if columns else MLTransform(**kw).with_transform(transforms(type_adapter=type_adapter))","typeGuard":"def transform_config_ok(cfg) -> bool:\n    return bool(cfg.get('columns')) or cfg.get('type_adapter') is not None","tryCatchPattern":"try:\n    t = MLTransform(...).with_transform(Embedding(model_handler=h, columns=cols))\nexcept ValueError as e:\n    if 'Either columns or type_adapter' in str(e):\n        raise ValueError('Embedding transform requires columns= or type_adapter=') from e\n    raise","preventionTips":["Always include columns= in every with_transform call","Lint pipeline code for MLTransform configs missing columns","Follow the official MLTransform example when scaffolding new pipelines"],"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"}