YunaiV/ruoyi-vue-pro · error · UnexpectedLiquibaseException
Unknown boolean value: {}
Error message
Unknown boolean value: {} What it means
Liquibase BooleanType.sqlToJava or equivalent string parsing rejects a value that is not recognized as true, false, or a Postgres bit-string literal. The branch list accepts 'true'/'1', 'false'/'0'/'f', and Postgres b'...'::bit patterns; anything else (e.g. 't', 'yes', 'Y', 'N', localized strings, null-ish text) reaches the else and throws UnexpectedLiquibaseException.
Source
Thrown at sql/dm/flowable-patch/src/main/java/liquibase/datatype/core/BooleanType.java:85
}
String returnValue;
if (value instanceof String) {
value = ((String) value).replaceAll("'", "");
if ("true".equals(((String) value).toLowerCase(Locale.US)) || "1".equals(value) || "b'1'".equals(((String) value).toLowerCase(Locale.US)) || "t".equals(((String) value).toLowerCase(Locale.US)) || ((String) value).toLowerCase(Locale.US).equals(this.getTrueBooleanValue(database).toLowerCase(Locale.US))) {
returnValue = this.getTrueBooleanValue(database);
} else if ("false".equals(((String) value).toLowerCase(Locale.US)) || "0".equals(value) || "b'0'".equals(
((String) value).toLowerCase(Locale.US)) || "f".equals(((String) value).toLowerCase(Locale.US)) || ((String) value).toLowerCase(Locale.US).equals(this.getFalseBooleanValue(database).toLowerCase(Locale.US))) {
returnValue = this.getFalseBooleanValue(database);
} else if (database instanceof PostgresDatabase && Pattern.matches("b?([01])\\1*(::bit|::\"bit\")?", (String) value)) {
returnValue = "b'"
+ value.toString()
.replace("b", "")
.replace("\"", "")
.replace("::it", "")
+ "'::\"bit\"";
} else {
throw new UnexpectedLiquibaseException("Unknown boolean value: " + value);
}
} else if (value instanceof Long) {
if (Long.valueOf(1).equals(value)) {
returnValue = this.getTrueBooleanValue(database);
} else {
returnValue = this.getFalseBooleanValue(database);
}
} else if (value instanceof Number) {
if (value.equals(1) || "1".equals(value.toString()) || "1.0".equals(value.toString())) {
returnValue = this.getTrueBooleanValue(database);
} else {
returnValue = this.getFalseBooleanValue(database);
}
} else if (value instanceof DatabaseFunction) {
return value.toString();
} else if (value instanceof Boolean) {
if (((Boolean) value)) {
returnValue = this.getTrueBooleanValue(database);View on GitHub (pinned to 0418084e22)
Solutions
- Normalize the boolean value before it reaches BooleanType: use 1/0, true/false, or the DB's canonical boolean keyword.
- If you must use 'Y'/'N' or 't'/'f', wrap the column as a non-boolean type (CHAR(1)) in the changeset instead of BOOLEAN.
- Register a custom Liquibase DataType to extend the accepted boolean vocabulary for your source DB.
- Check the changelog for defaultValueBoolean or valueBoolean with non-canonical text and replace it.
Example fix
// before <column name="active" type="BOOLEAN" defaultValue="Y"/> // after <column name="active" type="BOOLEAN" defaultValueBoolean="true"/>
Defensive patterns
Strategy: validation
Validate before calling
private static final Pattern BOOL = Pattern.compile("^(true|false|0|1|b'0|b'1|t|f)$", Pattern.CASE_INSENSITIVE);
if (value instanceof String && !BOOL.matcher(((String)value)).matches()) {
throw new IllegalArgumentException("Unrecognized boolean literal: " + value);
} Type guard
static boolean isLiquibaseBooleanLiteral(Object v) {
if (!(v instanceof String)) return false;
String s = ((String)v).toLowerCase(Locale.US);
return s.equals("true") || s.equals("false") || s.equals("0") || s.equals("1") || s.equals("f") || s.equals("b'0") || s.equals("b'1");
} Try / catch
try {
return booleanType.objectToSql(value, db);
} catch (UnexpectedLiquibaseException e) {
return "0"; // safe default, logged
} Prevention
- Use defaultValueBoolean=true/false in changesets, not free text
- Normalize boolean values to 1/0 at the data source
- Audit changesets for Y/N, yes/no, t/f literals
When it happens
Trigger: A changelog/column default or raw value supplies a boolean literal the parser does not whitelist ('t'/'yes'/'Y'/'TRUE' on non-Postgres DBs, 'no', 'n', empty string, or a DB-specific boolean keyword); migrating data from a DB whose boolean text differs from the expected set.
Common situations: Porting a schema from PostgreSQL (which uses 't'/'f') to MySQL/Oracle/Dameng; setting column defaultValue='Y'/'N' in a changeset; loading seed data with 'yes'/'no'.
Related errors
AI-assisted analysis of YunaiV/ruoyi-vue-pro@0418084e22 (2026-08-14).
Data as JSON: /api/errors/100277a3d12869a1.
Report an issue: GitHub.