{"record":{"id":"a3e4cadcac7337af","repo":"apache/beam","slug":"please-provide-exactly-one-of-a-list-of-feature-names-to","errorCode":null,"errorMessage":"Please provide exactly one of a list of feature names to fetch from online store (`feature_names`) or a feature service name for the Feast online feature store (`feature_service_name`).","messagePattern":"Please provide exactly one of a list of feature names to fetch from online store \\(`feature_names`\\) or a feature service name for the Feast online feature store \\(`feature_service_name`\\)\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"sdks/python/apache_beam/transforms/enrichment_handlers/feast_feature_store.py","lineNumber":61,"sourceCode":"def download_fs_yaml_file(gcs_fs_yaml_file: str):\n  \"\"\"Download the feature store config file for Feast.\"\"\"\n  try:\n    with FileSystems.open(gcs_fs_yaml_file, 'r') as gcs_file:\n      with tempfile.NamedTemporaryFile(suffix=LOCAL_FEATURE_STORE_YAML_FILENAME,\n                                       delete=False) as local_file:\n        local_file.write(gcs_file.read())\n        return Path(local_file.name)\n  except Exception:\n    raise RuntimeError(\n        'error downloading the file %s locally to load the '\n        'Feast feature store.' % gcs_fs_yaml_file)\n\n\ndef _validate_feature_names(feature_names, feature_service_name):\n  \"\"\"Check if one of `feature_names` or `feature_service_name` is provided.\"\"\"\n  if ((not feature_names and not feature_service_name) or\n      bool(feature_names and feature_service_name)):\n    raise ValueError(\n        'Please provide exactly one of a list of feature names to fetch '\n        'from online store (`feature_names`) or a feature service name for '\n        'the Feast online feature store (`feature_service_name`).')\n\n\ndef _validate_feature_store_yaml_path_exists(fs_yaml_file):\n  \"\"\"Check if the feature store yaml path exists.\"\"\"\n  if not FileSystems.exists(fs_yaml_file):\n    raise ValueError(\n        'The feature store yaml path (%s) does not exist.' % fs_yaml_file)\n\n\ndef _validate_entity_key_exists(entity_id, entity_row_fn):\n  \"\"\"Checks if the entity key or a lambda to build entity key exists.\"\"\"\n  if ((not entity_row_fn and not entity_id) or\n      bool(entity_row_fn and entity_id)):\n    raise ValueError(\n        \"Please specify exactly one of a `entity_id` or a lambda \"","sourceCodeStart":43,"sourceCodeEnd":79,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/python/apache_beam/transforms/enrichment_handlers/feast_feature_store.py#L43-L79","documentation":"Validation in `_validate_feature_names`, invoked from the handler's `__init__`, requires exactly one of `feature_names` (list) or `feature_service_name`. Passing neither, or passing both, raises this ValueError because the handler cannot decide how to resolve features from the Feast online store.","triggerScenarios":"Constructing `FeastFeatureStoreEnrichmentHandler(feature_store_yaml_path=...)` with both `feature_names=[...]` and `feature_service_name='fs'`, or with neither argument (both None/empty).","commonSituations":"Copy-pasting a config and forgetting to delete the other option; converting from feature_names to feature_service and leaving both; initializing with defaults and forgetting to set either.","solutions":["Pass exactly one of `feature_names` or `feature_service_name`; delete the other argument.","If migrating to a feature service, remove the `feature_names` list entirely (empty list still counts as absent, but keep code clean).","Check defaults in your wrapper/config class that may inject both values."],"exampleFix":"// before\nFeastFeatureStoreEnrichmentHandler(..., feature_names=['f1'], feature_service_name='daily_fs')\n// after\nFeastFeatureStoreEnrichmentHandler(..., feature_service_name='daily_fs')","handlingStrategy":"validation","validationCode":"assert bool(feature_names) != bool(feature_service_name), 'provide exactly one of feature_names or feature_service_name'","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Use keyword-only parameters so the exclusivity is documented.","Centralize handler construction in one factory function that enforces exclusivity.","Never default both options in config files."],"tags":["python","apache-beam","feast","validation"],"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-14T21:17:11.552Z"}