{"record":{"id":"9cc85b1e223bd781","repo":"apache/beam","slug":"invalid-value-fields-for-fields-fields-must-be-a-dict","errorCode":null,"errorMessage":"Invalid value \"{fields}\" for \"fields\". Fields must be a dict.","messagePattern":"Invalid value \"(.+?)\" for \"fields\"\\. Fields must be a dict\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"sdks/python/apache_beam/yaml/yaml_join.py","lineNumber":113,"sourceCode":"            f'{error_prefix} \"{pcoll_tag}\" is not a specified alias in \"input\"')\n      if col not in valid_cols[pcoll_tag]:\n        raise ValueError(\n            f'{error_prefix} \"{col}\" is not a valid field in \"{pcoll_tag}\".')\n\n    input_edge_list.append(tuple(equality.keys()))\n\n  if not _is_connected(input_edge_list, len(pcolls)):\n    raise ValueError(\n        f'{error_prefix} '\n        f'The provided equalities do not connect all of {list(pcolls.keys())}.')\n\n  return equalities\n\n\ndef _parse_fields(tables, fields):\n  error_prefix = f'Invalid value \"{fields}\" for \"fields\".'\n  if not isinstance(fields, dict):\n    raise ValueError(f'{error_prefix} Fields must be a dict.')\n  output_fields = []\n  named_columns = set()\n  for input, cols in fields.items():\n    if input not in tables:\n      raise ValueError(f'An invalid input \"{input}\" was specified in \"fields\".')\n    if isinstance(cols, list):\n      for col in cols:\n        if not isinstance(col, str):\n          raise ValueError(\n              f'Invalid column \"{col}\" in \"fields\". Column name must be a str.')\n        if col in named_columns:\n          raise ValueError(\n              f'The field name \"{col}\" was specified more than once.')\n        output_fields.append(f'{input}.{col} AS {col}')\n        named_columns.add(col)\n    elif isinstance(cols, dict):\n      for k, v in cols.items():\n        if k in named_columns:","sourceCodeStart":95,"sourceCodeEnd":131,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/python/apache_beam/yaml/yaml_join.py#L95-L131","documentation":"The optional 'fields' parameter of the SQL Join transform selects which columns each input contributes to the output. _parse_fields requires it to be a mapping from input alias to a list or dict of columns; if 'fields' is not a dict this ValueError is raised.","triggerScenarios":"Passing fields as a list (e.g. fields: [id, name]), a string (fields: id), or null/other non-dict value in the Join transform spec.","commonSituations":"Users assuming fields is a flat list of column names across all inputs; YAML indentation mistakes that turn the mapping into a list; copying config from a different transform with a different fields schema.","solutions":["Make fields a mapping of input alias -> list of columns (or alias -> {outputName: columnName} dict).","Quote/indent YAML correctly so the value parses as a dict.","Remove the fields key entirely to include all columns from all inputs."],"exampleFix":"// before\nfields: [id, name]\n// after\nfields:\n  left: [id, name]\n  right: [id, name]","handlingStrategy":"type-guard","validationCode":"if not isinstance(spec.get('fields'), dict):\n    raise ValueError('fields must be a mapping of input alias -> columns')","typeGuard":"def has_valid_fields_shape(spec):\n    f = spec.get('fields')\n    return f is None or (isinstance(f, dict) and all(isinstance(v, (list, dict)) for v in f.values()))","tryCatchPattern":"try:\n    result = SqlJoinTransform(config)\nexcept ValueError as e:\n    if 'Fields must be a dict' in str(e):\n        raise ConfigError('fields must map input aliases to column lists/dicts') from e\n    raise","preventionTips":["Remember fields is per-input: alias -> list-or-dict","Check YAML indentation so fields parses as a mapping","Use a JSON/YAML schema validator on the pipeline spec"],"tags":["apache-beam","yaml","validation","fields"],"backgroundTag":"type-mismatch","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"}