{"record":{"id":"34c5d77a4e296bf3","repo":"apache/beam","slug":"make-sure-the-values-passed-in-fields-are-the-keys-in-the","errorCode":null,"errorMessage":"Make sure the values passed in `fields` are the keys in the input `beam.Row`.","messagePattern":"Make sure the values passed in `fields` are the keys in the input `beam\\.Row`\\.","errorType":"validation","errorClass":"KeyError","httpStatus":null,"severity":"error","filePath":"sdks/python/apache_beam/transforms/enrichment_handlers/bigquery.py","lineNumber":216,"sourceCode":"    if isinstance(request, list):\n      values = []\n      responses = []\n      requests_map: dict[Any, list[beam.Row]] = defaultdict(list)\n      batch_size = len(request)\n      raw_query = self.query_template\n      if batch_size > 1:\n        batched_condition_template = ' or '.join(\n            [fr'({self.row_restriction_template})'] * batch_size)\n        raw_query = self.query_template.replace(\n            self.row_restriction_template, batched_condition_template)\n      for req in request:\n        request_dict = req._asdict()\n        try:\n          current_values = (\n              self.condition_value_fn(req) if self.condition_value_fn else\n              [request_dict[field] for field in self.fields])\n        except KeyError as e:\n          raise KeyError(\n              \"Make sure the values passed in `fields` are the \"\n              \"keys in the input `beam.Row`.\" + str(e))\n        values.extend(current_values)\n        requests_map[self.create_row_key(req)].append(req)\n      query = raw_query.format(*values)\n\n      responses_dict = self._execute_query(query)\n      unmatched_requests = {\n          key: list(reqs)\n          for key, reqs in requests_map.items()\n      }\n      if responses_dict:\n        for response in responses_dict:\n          response_row = beam.Row(**response)\n          response_key = self.create_row_key(response_row)\n          if response_key in unmatched_requests:\n            for req in unmatched_requests.pop(response_key):\n              responses.append((req, response_row))","sourceCodeStart":198,"sourceCodeEnd":234,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/python/apache_beam/transforms/enrichment_handlers/bigquery.py#L198-L234","documentation":"When building format values for the query, __call__ reads request_dict[field] for each field in self.fields. A KeyError means a field listed in fields is not present in the input beam.Row; it is re-raised with this guidance message.","triggerScenarios":"Input beam.Row lacks a key named in self.fields (typo, renamed column, upstream transform changed schema).","commonSituations":"Field name mismatch between handler config and upstream PCollection schema; case-sensitivity mistakes; nullable/absent columns removed by earlier transformations.","solutions":["Align self.fields with the actual keys of the input beam.Row (print row._asdict() keys)","Fix typos/casing in the fields list","Add the missing column upstream or use condition_value_fn to derive values defensively"],"exampleFix":"// before\nBigQueryEnrichmentHandler(..., fields=['userID'])\n// after (matches row key)\nBigQueryEnrichmentHandler(..., fields=['user_id'])","handlingStrategy":"validation","validationCode":"def validate_fields_in_row(fields, row):\n    missing = [f for f in fields if f not in row._asdict()]\n    if missing:\n        raise KeyError(f'fields missing from input Row: {missing}; have {list(row._asdict())}')","typeGuard":"def row_has_fields(fields, row) -> bool:\n    d = row._asdict()\n    return all(f in d for f in fields)","tryCatchPattern":"try:\n    out = handler(row)\nexcept KeyError as e:\n    logger.error('Enrichment key mismatch: %s', e)\n    raise","preventionTips":["Derive fields from the actual Row schema (beam.Row asdict keys) rather than hardcoding","Add a schema assertion step upstream in the pipeline","Watch for renames when refactoring upstream transforms"],"tags":["apache-beam","bigquery","keyerror","schema"],"backgroundTag":"schema-validation-failed","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"}