{"record":{"id":"532f2e2b0e5ad085","repo":"apache/beam","slug":"format-of-provided-table-schema-is-invalid","errorCode":null,"errorMessage":"Format of provided table schema is invalid","messagePattern":"Format of provided table schema is invalid","errorType":"validation","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"sdks/java/io/snowflake/src/main/java/org/apache/beam/sdk/io/snowflake/crosslanguage/WriteBuilder.java","lineNumber":51,"sourceCode":"  \"nullness\" // TODO(https://github.com/apache/beam/issues/20497)\n})\npublic class WriteBuilder\n    implements ExternalTransformBuilder<\n        WriteBuilder.Configuration, PCollection<List<byte[]>>, PDone> {\n\n  /** Parameters class to expose the transform to an external SDK. */\n  public static class Configuration extends CrossLanguageConfiguration {\n    private SnowflakeTableSchema tableSchema;\n    private CreateDisposition createDisposition;\n    private WriteDisposition writeDisposition;\n\n    public void setTableSchema(String tableSchema) {\n      ObjectMapper mapper = new ObjectMapper();\n\n      try {\n        this.tableSchema = mapper.readValue(tableSchema, SnowflakeTableSchema.class);\n      } catch (IOException e) {\n        throw new RuntimeException(\"Format of provided table schema is invalid\");\n      }\n    }\n\n    public void setCreateDisposition(String createDisposition) {\n      this.createDisposition = CreateDisposition.valueOf(createDisposition);\n    }\n\n    public void setWriteDisposition(String writeDisposition) {\n      this.writeDisposition = WriteDisposition.valueOf(writeDisposition);\n    }\n\n    public SnowflakeTableSchema getTableSchema() {\n      return tableSchema;\n    }\n\n    public CreateDisposition getCreateDisposition() {\n      return createDisposition;\n    }","sourceCodeStart":33,"sourceCodeEnd":69,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/java/io/snowflake/src/main/java/org/apache/beam/sdk/io/snowflake/crosslanguage/WriteBuilder.java#L33-L69","documentation":"WriteBuilder.setTableSchema() (Snowflake cross-language Java API) deserializes the tableSchema string into SnowflakeTableSchema with Jackson. If the string is not valid JSON or does not match the expected schema shape, the IOException is converted to a RuntimeException with this message, aborting cross-language pipeline expansion.","triggerScenarios":"Calling setTableSchema() with a non-JSON string, JSON that isn't an array of column objects, or malformed input from a Python/YAML side that wasn't converted with to_json.","commonSituations":"Python Beam users passing a Python list/dict repr (single quotes, unquoted keys) instead of JSON; hand-written schema strings with trailing commas or comments; double-escaping issues when the JSON travels through pipeline options.","solutions":["Pass valid JSON matching SnowflakeTableSchema, e.g. '[{\"name\":\"id\",\"type\":\"NUMBER\"}]', with double quotes.","On the Python side, use json.dumps(schema_list) before handing the value to the Java transform.","Validate the string with json.loads (Python) or a JSON linter before calling setTableSchema; check for shell/option escaping issues."],"exampleFix":"// before\nbuilder.setTableSchema(\"[{name: 'id', type: 'NUMBER'}]\")\n// after\nbuilder.setTableSchema(\"[{\\\"name\\\":\\\"id\\\",\\\"type\\\":\\\"NUMBER\\\"}]\")","handlingStrategy":"try-catch","validationCode":"import json\ncolumns = [{\"name\": \"id\", \"type\": \"NUMBER\"}]\njson.dumps(columns)  # validate before passing to setTableSchema","typeGuard":"function isValidTableSchemaJson(s) {\n  try {\n    const v = JSON.parse(s);\n    return Array.isArray(v) && v.every(c => typeof c.name === 'string' && typeof c.type === 'string');\n  } catch { return false; }\n}","tryCatchPattern":"try {\n  builder.setTableSchema(tableSchemaJson);\n} catch (RuntimeException e) {\n  if (e.getMessage().contains(\"Format of provided table schema is invalid\")) {\n    // re-parse/repair the JSON on the producing side before retrying\n  }\n  throw e;\n}","preventionTips":["Generate the schema string with json.dumps / a JSON serializer, never string concatenation or Python repr().","Validate the JSON with a parser on the producing side before handing it to the cross-language transform.","Beware double-escaping when passing JSON through pipeline options or shell commands."],"tags":["java","json","snowflake","xlang"],"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"}