{"record":{"id":"bb82465e4d4573d0","repo":"apache/beam","slug":"unable-to-parse-json-schema-s-r","errorCode":null,"errorMessage":"Unable to parse JSON schema: %s - %r","messagePattern":"Unable to parse JSON schema: (.+?) - %r","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"sdks/python/apache_beam/io/gcp/bigquery_tools.py","lineNumber":216,"sourceCode":"  \"\"\"\n  table_ref = table_ref_elem_kv[0]\n  hashable_table_ref = get_hashable_destination(table_ref)\n  return (hashable_table_ref, table_ref_elem_kv[1])\n\n\ndef parse_table_schema_from_json(schema_string):\n  \"\"\"Parse the Table Schema provided as string.\n\n  Args:\n    schema_string: String serialized table schema, should be a valid JSON.\n\n  Returns:\n    A TableSchema of the BigQuery export from either the Query or the Table.\n  \"\"\"\n  try:\n    json_schema = json.loads(schema_string)\n  except JSONDecodeError as e:\n    raise ValueError(\n        'Unable to parse JSON schema: %s - %r' % (schema_string, e))\n\n  def _parse_schema_field(field):\n    \"\"\"Parse a single schema field from dictionary.\n\n    Args:\n      field: Dictionary object containing serialized schema.\n\n    Returns:\n      A TableFieldSchema for a single column in BigQuery.\n    \"\"\"\n    schema = bigquery.TableFieldSchema()\n    schema.name = field['name']\n    schema.type = field['type']\n    if 'mode' in field:\n      schema.mode = field['mode']\n    else:\n      schema.mode = 'NULLABLE'","sourceCodeStart":198,"sourceCodeEnd":234,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/python/apache_beam/io/gcp/bigquery_tools.py#L198-L234","documentation":"Raised by parse_table_schema_from_json when the schema string passed in is not valid JSON (json.loads raises JSONDecodeError). Beam wraps it in a ValueError including the original string and the decoder error so the malformed schema can be located.","triggerScenarios":"Calling parse_table_schema_from_json(schema_string) with a non-JSON string — e.g. a Python-dict repr, single-quoted JSON, trailing commas, or a stringified dict from logging output.","commonSituations":"Pasting a schema dict from Python repr form (single quotes) into config; using WriteToBigQuery(schema='...') where the string is expected to be JSON but users pass a Python dict literal; reading a schema from an env var or file that was corrupted.","solutions":["Validate the string with json.loads(schema_string) locally to see the exact JSONDecodeError position.","Convert Python dict literals to valid JSON using double quotes: json.dumps(python_dict) before storing/passing.","If you have a dict already, pass it via the dict-based schema path or call json.dumps on it first.","Check the source (file/env var/CLI arg) isn't truncated or wrapped in quotes."],"exampleFix":"# before\nparse_table_schema_from_json(\"{'fields': [{'name': 'x', 'type': 'STRING'}]}\")\n\n# after\nparse_table_schema_from_json('{\"fields\": [{\"name\": \"x\", \"type\": \"STRING\"}]}')","handlingStrategy":"validation","validationCode":"import json\ndef validate_schema_string(s):\n    if isinstance(s, str):\n        json.loads(s)  # raises before Beam does","typeGuard":"def is_valid_json(s):\n    if not isinstance(s, str):\n        return False\n    try:\n        json.loads(s)\n        return True\n    except ValueError:\n        return False","tryCatchPattern":"try:\n    schema = parse_table_schema_from_json(s)\nexcept ValueError as e:\n    if 'Unable to parse JSON schema' in str(e):\n        raise ConfigError('schema string must be valid JSON (double quotes)') from e\n    raise","preventionTips":["Store schemas as json.dumps() output, never Python repr","Validate schema strings in CI with json.loads","Prefer passing dict schemas or TableSchema objects instead of raw strings"],"tags":["json","parse","bigquery","schema"],"backgroundTag":"json-parse-error","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"}