{"record":{"id":"72dee1b46ff8436e","repo":"apache/beam","slug":"expected-object-type-got-json-type","errorCode":null,"errorMessage":"Expected object type, got {json_type}.","messagePattern":"Expected object type, got (.+?)\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"sdks/python/apache_beam/yaml/json_utils.py","lineNumber":66,"sourceCode":"    schema_pb2.FLOAT: 'number',\n    **{\n        v: k\n        for k, v in JSON_ATOMIC_TYPES_TO_BEAM.items()\n    }\n}\n\n\ndef json_schema_to_beam_schema(\n    json_schema: dict[str, Any]) -> schema_pb2.Schema:\n  \"\"\"Returns a Beam schema equivalent for the given Json schema.\"\"\"\n  def maybe_nullable(beam_type, nullable):\n    if nullable:\n      beam_type.nullable = True\n    return beam_type\n\n  json_type = json_schema.get('type', None)\n  if json_type != 'object':\n    raise ValueError(f'Expected object type, got {json_type}.')\n  if 'properties' not in json_schema:\n    # Technically this is a valid (vacuous) schema, but as it's not generally\n    # meaningful, throw an informative error instead.\n    # (We could add a flag to allow this degenerate case.)\n    raise ValueError('Missing properties for {json_schema}.')\n  required = set(json_schema.get('required', []))\n  return schema_pb2.Schema(\n      fields=[\n          schemas.schema_field(\n              name,\n              maybe_nullable(json_type_to_beam_type(t), name not in required),\n              description=t.get('description') if isinstance(t, dict) else None)\n          for (name, t) in json_schema['properties'].items()\n      ])\n\n\ndef json_type_to_beam_type(json_type: dict[str, Any]) -> schema_pb2.FieldType:\n  \"\"\"Returns a Beam schema type for the given Json (schema) type.\"\"\"","sourceCodeStart":48,"sourceCodeEnd":84,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/python/apache_beam/yaml/json_utils.py#L48-L84","documentation":"json_schema_to_beam_schema converts a JSON Schema into a Beam schema, but only handles top-level object schemas. If the schema's 'type' field is anything other than 'object' (or absent), it raises ValueError. JSON schemas describing arrays, strings, or numbers at the root are not supported for Beam row conversion.","triggerScenarios":"Passing a JSON schema dict whose json_schema['type'] is not exactly 'object' (e.g. 'array', 'string', or missing) to json_schema_to_beam_schema, typically via json_type_to_beam_type or the yaml json_schema option of transforms like ReadFromJson/WriteToJson.","commonSituations":"Feeding a root-level array or primitive JSON schema meant for the payload itself rather than the row; copying a schema fragment (e.g. an item schema of an array) instead of the wrapping object schema; typo like 'typo': 'object' leaving 'type' unset.","solutions":["Wrap the schema in an object: {\"type\":\"object\",\"properties\":{\"items\":{\"type\":\"array\",\"items\":<your schema>}}}]","Set json_schema['type'] to 'object' and define its 'properties'","Verify you are passing the whole record schema, not a nested field's schema"],"exampleFix":"// before\n{\"type\": \"array\", \"items\": {\"type\": \"string\"}}\n// after\n{\"type\": \"object\", \"properties\": {\"items\": {\"type\": \"array\", \"items\": {\"type\": \"string\"}}}}","handlingStrategy":"validation","validationCode":"def assert_root_object_schema(json_schema):\n    if not isinstance(json_schema, dict) or json_schema.get('type') != 'object':\n        raise ValueError('Root JSON schema must be {\"type\": \"object\", ...}')","typeGuard":"def is_object_schema(s) -> bool:\n    return isinstance(s, dict) and s.get('type') == 'object'","tryCatchPattern":"try:\n    beam_schema = json_schema_to_beam_schema(json_schema)\nexcept ValueError as e:\n    raise ValueError(f'Invalid root JSON schema for Beam conversion: {e}') from e","preventionTips":["Always make the root of the schema an object with 'properties'","Wrap array/primitive payloads in a top-level record field","Validate the schema with a JSON Schema validator before passing it to Beam yaml transforms"],"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"}