OtterMind/Chat2DB · error · IllegalArgumentException
Unsafe H2 column default from metadata: {columnDefault}
Error message
Unsafe H2 column default from metadata: {columnDefault} What it means
Thrown by H2SqlGuards.escapeColumnDefault when a non-null JDBC metadata column default does not match any accepted literal/expression pattern (string literal, numeric literal, NULL/TRUE/FALSE, CURRENT_TEMPORAL, no-arg function, typed literal, binary literal, or NEXT VALUE FOR sequence). Null defaults return ""; everything else unrecognized is rejected rather than silently re-quoted into a semantically different string literal.
Source
Thrown at chat2db-community-server/chat2db-community-plugins/chat2db-community-h2/src/main/java/ai/chat2db/plugin/h2/H2SqlGuards.java:125
* silently converted into a string literal with different semantics.
* Returns an empty string for {@code null}.
*/
public static String escapeColumnDefault(String columnDefault) {
if (columnDefault == null) {
return "";
}
String trimmed = columnDefault.trim();
if (STRING_LITERAL.matcher(trimmed).matches()
|| NUMERIC_LITERAL.matcher(trimmed).matches()
|| SIMPLE_CONSTANT.matcher(trimmed).matches()
|| CURRENT_TEMPORAL.matcher(trimmed).matches()
|| SAFE_NO_ARG_FUNCTION.matcher(trimmed).matches()
|| TYPED_LITERAL.matcher(trimmed).matches()
|| BINARY_LITERAL.matcher(trimmed).matches()
|| SEQUENCE_EXPRESSION.matcher(trimmed).matches()) {
return trimmed;
}
throw new IllegalArgumentException("Unsafe H2 column default from metadata: " + columnDefault);
}
}
View on GitHub (pinned to 5ee1e990e7)
Solutions
- Verify the default expression is one of the allow-listed forms; if it is a function with arguments, extend the guard pattern or handle that column manually.
- Leave the default null/blank to emit no DEFAULT clause.
- If a legitimate H2 default is rejected, report it so the allow-list pattern can be widened rather than bypassing the guard.
Example fix
// before
// metadata default = "NOW(0)" works, but "MYFUNC(1)" fails
H2SqlGuards.escapeColumnDefault("MYFUNC(1)");
// after
// drop the unsupported default for this column, or whitelist MYFUNC
String d = column.getDefaultValue();
String safe = (d == null || isKnownSafeDefault(d)) ? H2SqlGuards.escapeColumnDefault(d) : null; Defensive patterns
Strategy: validation
Validate before calling
// Reuse the same allow-list checks H2SqlGuards applies internally is not exposed,
// so validate structurally before calling escapeColumnDefault:
static boolean looksLikeSafeH2Default(String d) {
if (d == null) return true;
String t = d.trim();
return t.isEmpty()
|| t.matches("'(?:''|[^'])*'")
|| t.matches("^[+-]?(?:\\d+(?:\\.\\d*)?|\\.\\d+)(?:[eE][+-]?\\d+)?$")
|| t.matches("(?i)^(?:NULL|TRUE|FALSE)$");
} Try / catch
try {
ddl.append(H2SqlGuards.escapeColumnDefault(def));
} catch (IllegalArgumentException e) {
// Drop the DEFAULT clause for this column and surface a warning;
// do NOT stringify the value into quotes (it changes semantics).
log.warn("Skipping unsafe H2 default for column: {}", def);
} Prevention
- Prefer allow-listed H2 default forms (literal, CURRENT_TIMESTAMP, NEXT VALUE FOR).
- Never coerce an unknown default into a quoted string to silence the guard.
- Report legitimately-rejected H2 defaults so the pattern can be widened.
When it happens
Trigger: Calling escapeColumnDefault(columnDefault) where columnDefault is a complex expression, function call with arguments, arithmetic, CASE/CAST, or any text outside the eight allow-listed forms.
Common situations: H2 metadata reporting a DEFAULT that references a user function or expression; a schema using DEFAULT CURRENT_TIMESTAMP... that doesn't match the strict pattern; metadata from a newer H2 that emits a default format the guard doesn't recognize.
Related errors
- Unsafe column type name from metadata: {typeName}
- Invalid Hive default value: {value}
- Invalid DB2 index column ordering: {ascOrDesc}
- Unsupported DM VARCHAR unit: {unit}
- Invalid DM index sort direction: {value}
AI-assisted analysis of OtterMind/Chat2DB@5ee1e990e7 (2026-08-14).
Data as JSON: /api/errors/562577be4622e20c.
Report an issue: GitHub.