{"record":{"id":"ae2c5c71ae3bec59","repo":"apache/beam","slug":"incompatible-types-map-vs-object","errorCode":null,"errorMessage":"Incompatible types: map vs object","messagePattern":"Incompatible types: map vs object","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"sdks/python/apache_beam/yaml/json_utils.py","lineNumber":325,"sourceCode":"  convert = row_to_json(\n      schema_pb2.FieldType(row_type=schema_pb2.RowType(schema=beam_schema)))\n  return lambda row: json.dumps(convert(row), sort_keys=True).encode('utf-8')\n\n\ndef _validate_compatible(weak_schema, strong_schema):\n  if not weak_schema:\n    return\n  if weak_schema['type'] != strong_schema['type']:\n    raise ValueError(\n        f\"Incompatible types: {weak_schema['type']} vs {strong_schema['type']}\")\n  if weak_schema['type'] == 'array':\n    _validate_compatible(weak_schema['items'], strong_schema['items'])\n  elif weak_schema['type'] == 'object':\n    # If the weak schema allows for arbitrary keys (is a map),\n    # the strong schema must also allow for arbitrary keys.\n    if weak_schema.get('additionalProperties'):\n      if not strong_schema.get('additionalProperties', True):\n        raise ValueError('Incompatible types: map vs object')\n      _validate_compatible(\n          weak_schema['additionalProperties'],\n          strong_schema['additionalProperties'])\n    for required in strong_schema.get('required', []):\n      if required not in weak_schema['properties']:\n        raise ValueError(f\"Missing or unknown property '{required}'\")\n    for name, spec in weak_schema.get('properties', {}).items():\n\n      if name in strong_schema['properties']:\n        try:\n          _validate_compatible(spec, strong_schema['properties'][name])\n        except Exception as exn:\n          raise ValueError(f\"Incompatible schema for '{name}'\") from exn\n      elif not strong_schema.get('additionalProperties', True):\n        # The property is not explicitly in the strong schema, and the strong\n        # schema does not allow for extra properties.\n        raise ValueError(\n            f\"Prohibited property: '{name}'; \"","sourceCodeStart":307,"sourceCodeEnd":343,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/python/apache_beam/yaml/json_utils.py#L307-L343","documentation":"When the weak schema is of type 'object' but allows arbitrary keys (additionalProperties set, i.e. a map), the strong schema must also allow arbitrary keys. If strong_schema has additionalProperties falsy (e.g. False or an empty spec), the validator raises 'Incompatible types: map vs object'.","triggerScenarios":"row_validator with weak_schema = {'type': 'object', 'additionalProperties': <schema>} and strong_schema = {'type': 'object', 'additionalProperties': False} (or missing property-restricted schema) for the same position.","commonSituations":"Beam map<str, X> fields being validated against a strict JSON object schema with enumerated properties; tightening a previously open schema; YAML map fields declared with fixed property lists.","solutions":["Set additionalProperties in the strong schema (to the value schema or true) so a map is accepted.","Alternatively change the source so it produces a fixed-shape object matching the strong schema's properties instead of an arbitrary map.","If strictness is required, convert the Beam side from a map type to a Row/struct with explicit fields.","Split validation: validate map values against a separate schema rather than through this object-vs-object path."],"exampleFix":"# before\nstrong = {'type': 'object', 'properties': {'a': {'type': 'string'}}, 'additionalProperties': False}\n# after\nstrong = {'type': 'object', 'additionalProperties': {'type': 'string'}}","handlingStrategy":"type-guard","validationCode":"def map_compatible(weak, strong):\n    if weak.get('type') != 'object':\n        return True\n    if weak.get('additionalProperties'):\n        return bool(strong.get('additionalProperties', True))\n    return True\nassert map_compatible(weak_schema, strong_schema)","typeGuard":"def is_map_schema(s):\n    return isinstance(s, dict) and s.get('type') == 'object' and bool(s.get('additionalProperties'))","tryCatchPattern":"try:\n    row_validator(beam_schema, json_schema)\nexcept ValueError as e:\n    if str(e) == 'Incompatible types: map vs object':\n        raise ValueError('Source emits a map; consumer schema must allow additionalProperties') from e\n    raise","preventionTips":["Use Beam map types only when keys are truly dynamic; prefer Rows with explicit fields.","When tightening a schema, check every producer for map-shaped fields first.","Keep additionalProperties consistent across weak and strong schemas by convention."],"tags":["python","apache-beam","yaml","json-schema","map-vs-object"],"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-14T16:17:12.679Z"}