{"record":{"id":"d262a71bdd0e1326","repo":"apache/beam","slug":"please-specify-exactly-one-of-a-entity-id-or-a-lambda","errorCode":null,"errorMessage":"Please specify exactly one of a `entity_id` or a lambda function with `entity_row_fn` to extract the entity id from the input row.","messagePattern":"Please specify exactly one of a `entity_id` or a lambda function with `entity_row_fn` to extract the entity id from the input row\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"sdks/python/apache_beam/transforms/enrichment_handlers/feast_feature_store.py","lineNumber":78,"sourceCode":"      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 \"\n        \"function with `entity_row_fn` to extract the entity id \"\n        \"from the input row.\")\n\n\nclass FeastFeatureStoreEnrichmentHandler(EnrichmentSourceHandler[beam.Row,\n                                                                 beam.Row]):\n  \"\"\"Enrichment handler to interact with the Feast feature store.\n\n  To specify the features to fetch from Feast online store,\n  please specify exactly one of `feature_names` or `feature_service_name`.\n\n  Use this handler with :class:`apache_beam.transforms.enrichment.Enrichment`\n  transform. To filter the features to enrich, use the `join_fn` param in\n  :class:`apache_beam.transforms.enrichment.Enrichment`.\n  \"\"\"\n  def __init__(\n      self,","sourceCodeStart":60,"sourceCodeEnd":96,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/python/apache_beam/transforms/enrichment_handlers/feast_feature_store.py#L60-L96","documentation":"Raised by `_validate_entity_key_exists` from `__init__` when the handler is constructed with neither `entity_id` nor `entity_row_fn`, or with both. The handler needs exactly one way to derive the entity key (a static column name, or a lambda building the key from the row) to look up features in the Feast online store.","triggerScenarios":"Constructing `FeastFeatureStoreEnrichmentHandler` with both `entity_id='user_id'` and `entity_row_fn=lambda row: ...`, or omitting both parameters entirely.","commonSituations":"Config merging where two layers each set a different entity option; forgetting the entity parameter when adding the handler to an existing pipeline template.","solutions":["Provide exactly one: a column name via `entity_id`, or a key-building lambda via `entity_row_fn`.","Remove the redundant second option when both are set.","Use `entity_row_fn` when the entity key must be composed from multiple row fields."],"exampleFix":"// before\nFeastFeatureStoreEnrichmentHandler(..., entity_id='id', entity_row_fn=lambda row: row['id'])\n// after\nFeastFeatureStoreEnrichmentHandler(..., entity_id='id')","handlingStrategy":"validation","validationCode":"assert bool(entity_id) != bool(entity_row_fn), 'provide exactly one of entity_id or entity_row_fn'","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Choose one convention per pipeline (prefer entity_id for simple columns).","Review constructor kwargs for accidental duplication from config merging.","Write a smoke test that constructs the handler before submission."],"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-15T02:17:10.978Z"}