apache/beam · error · IllegalArgumentException
failed to parse
Error message
failed to parse
What it means
TableSchema.parse(str) parses a ClickHouse column-definition string (e.g. "name String, age Int32") with the generated grammar parser. Any ParseException (syntax), TokenMgrError (lexical), or IllegalArgumentException (validation) raised during parsing is deliberately rethrown as a single IllegalArgumentException("failed to parse", cause) so callers face one error surface.
Solutions
- Inspect the wrapped cause (getCause()) — it names the exact syntax/validation problem and position.
- Fix the schema string to be a comma-separated list of valid ClickHouse column definitions only (no CREATE TABLE wrapper).
- Verify every type name is a ClickHouse type the parser supports (e.g. String, Int32, DateTime, Nullable(...)).
Example fix
// before
TableSchema.parse("CREATE TABLE t (id Int64) ENGINE = MergeTree()"); // fails
// after
TableSchema.parse("id Int64, name String"); Defensive patterns
Strategy: try-catch
Validate before calling
// regex sanity check that each column looks like "name Type" before parsing
for (String col : schemaStr.split(",")) {
if (!col.trim().matches("[`]?[A-Za-z_][A-Za-z0-9_`]*\\s+\\S+.*")) throw new IllegalArgumentException("bad column: " + col);
} Try / catch
try {
schema = TableSchema.parse(str);
} catch (IllegalArgumentException e) {
LOG.error("Schema parse failed: {}", e.getCause() != null ? e.getCause().getMessage() : e.getMessage());
throw e;
} Prevention
- Always inspect getCause() — the original ParseException/TokenMgrError pinpoints the syntax error.
- Pass only the bare column list, never a full CREATE TABLE statement.
- Validate type names against supported ClickHouse types before parsing.
When it happens
Trigger: Calling TableSchema.parse with a malformed DDL fragment: missing commas between columns, unknown type names, unbalanced parentheses, invalid Nullable/ LowCardinality usage, or non-column tokens.
Common situations: Copy-pasting a full CREATE TABLE statement (with backticks, ENGINE clauses, etc.) instead of the bare column list, typos in ClickHouse type names, or programmatically generated schema strings with formatting bugs.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- 'CREATE TABLE' is not supported in SQL. You can use 'CREATE…
- DateTime64 precision must be in [0, 9], got
- Decimal precision must be in [1, 76], got
- Decimal scale must be in [0, ], got
- Failed to get table schema for table:
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/ae4232dd64b2f522.
Report an issue: GitHub.
Appendix: source
Thrown at sdks/java/io/clickhouse/src/main/java/org/apache/beam/sdk/io/clickhouse/TableSchema.java:410
}
/**
* Parse string with ClickHouse type to {@link ColumnType}.
*
* @param str string representation of ClickHouse type
* @return type of ClickHouse column
* @throws IllegalArgumentException if {@code str} is not a valid ClickHouse column type
*/
public static ColumnType parse(String str) {
try {
return new org.apache.beam.sdk.io.clickhouse.impl.parser.ColumnTypeParser(
new StringReader(str))
.parse();
} catch (org.apache.beam.sdk.io.clickhouse.impl.parser.ParseException
| org.apache.beam.sdk.io.clickhouse.impl.parser.TokenMgrError
| IllegalArgumentException e) {
// Funnel lexical, syntactic and validation failures into one error surface.
throw new IllegalArgumentException("failed to parse", e);
}
}
/**
* Get default value of a column based on expression.
*
* <p>E.g., "CREATE TABLE hits(id Int32, count Int32 DEFAULT <str>)"
*
* @param columnType type of ClickHouse expression
* @param value ClickHouse expression
* @return value of ClickHouse expression
*/
public static Object parseDefaultExpression(ColumnType columnType, String value) {
switch (columnType.typeName()) {
case INT8:
return Byte.valueOf(value);
case INT16:
return Short.valueOf(value);View on GitHub (pinned to 12126d8942)