{"record":{"id":"3bf938525eb82a5c","repo":"apache/beam","slug":"object-type-must-have-either-properties-or","errorCode":null,"errorMessage":"Object type must have either properties or additionalProperties, got {json_type}.","messagePattern":"Object type must have either properties or additionalProperties, got (.+?)\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"sdks/python/apache_beam/yaml/json_utils.py","lineNumber":107,"sourceCode":"    return schema_pb2.FieldType(\n        atomic_type=JSON_ATOMIC_TYPES_TO_BEAM[type_name])\n  elif type_name == 'array':\n    return schema_pb2.FieldType(\n        array_type=schema_pb2.ArrayType(\n            element_type=json_type_to_beam_type(json_type['items'])))\n  elif type_name == 'object':\n    if 'properties' in json_type:\n      return schema_pb2.FieldType(\n          row_type=schema_pb2.RowType(\n              schema=json_schema_to_beam_schema(json_type)))\n    elif 'additionalProperties' in json_type:\n      return schema_pb2.FieldType(\n          map_type=schema_pb2.MapType(\n              key_type=schema_pb2.FieldType(atomic_type=schema_pb2.STRING),\n              value_type=json_type_to_beam_type(\n                  json_type['additionalProperties'])))\n    else:\n      raise ValueError(\n          f'Object type must have either properties or additionalProperties, '\n          f'got {json_type}.')\n  else:\n    raise ValueError(f'Unable to convert {json_type} to a Beam schema.')\n\n\ndef beam_schema_to_json_schema(\n    beam_schema: schema_pb2.Schema) -> dict[str, Any]:\n  return {\n      'type': 'object',\n      'properties': {\n          field.name: beam_type_to_json_type(field.type)\n          for field in beam_schema.fields\n      },\n      'additionalProperties': False\n  }\n\n","sourceCodeStart":89,"sourceCodeEnd":125,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/python/apache_beam/yaml/json_utils.py#L89-L125","documentation":"When json_type_to_beam_type sees an object-typed JSON schema, it needs either 'properties' (to build a row type) or 'additionalProperties' (to build a map type). An object schema with neither leaves the Beam mapping undefined, so ValueError is raised listing the offending schema.","triggerScenarios":"A nested schema like {\"type\": \"object\"} inside 'properties' with no 'properties' and no 'additionalProperties' key, converted via json_type_to_beam_type (reachable from json_schema_to_beam_schema).","commonSituations":"Nested record fields left undeclared in hand-written schemas; schema generated from records that were all null/empty; copying an incomplete schema fragment into a pipeline YAML.","solutions":["Declare the nested fields: add a 'properties' mapping to the nested object schema","If the nested value is a string->X map, add \"additionalProperties\": {\"type\": ...}","Remove the empty nested object if the field is unused"],"exampleFix":"// before\n{\"type\": \"object\", \"properties\": {\"meta\": {\"type\": \"object\"}}}\n// after\n{\"type\": \"object\", \"properties\": {\"meta\": {\"type\": \"object\", \"properties\": {\"created\": {\"type\": \"string\"}}}}}","handlingStrategy":"validation","validationCode":"def assert_object_defined(s):\n    if isinstance(s, dict) and s.get('type') == 'object' and 'properties' not in s and 'additionalProperties' not in s:\n        raise ValueError(f'Nested object schema {s!r} needs properties or additionalProperties')","typeGuard":"def is_defined_object(s) -> bool:\n    return not (isinstance(s, dict) and s.get('type') == 'object' and 'properties' not in s and 'additionalProperties' not in s)","tryCatchPattern":"try:\n    beam_type = json_type_to_beam_type(s)\nexcept ValueError as e:\n    raise ValueError(f'Undeclared nested object in schema: {e}') from e","preventionTips":["Declare every nested record's fields explicitly","Use additionalProperties for free-form maps at nested levels","Run schema validation over the whole document, including nested schemas"],"tags":["python","apache-beam","json-schema","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"}