{"record":{"id":"100277a3d12869a1","repo":"YunaiV/ruoyi-vue-pro","slug":"unknown-boolean-value","errorCode":null,"errorMessage":"Unknown boolean value: {}","messagePattern":"Unknown boolean value: (.+?)","errorType":"exception","errorClass":"UnexpectedLiquibaseException","httpStatus":null,"severity":"error","filePath":"sql/dm/flowable-patch/src/main/java/liquibase/datatype/core/BooleanType.java","lineNumber":85,"sourceCode":"        }\n\n        String returnValue;\n        if (value instanceof String) {\n            value = ((String) value).replaceAll(\"'\", \"\");\n            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))) {\n                returnValue = this.getTrueBooleanValue(database);\n            } else if (\"false\".equals(((String) value).toLowerCase(Locale.US)) || \"0\".equals(value) || \"b'0'\".equals(\n                ((String) value).toLowerCase(Locale.US)) || \"f\".equals(((String) value).toLowerCase(Locale.US)) || ((String) value).toLowerCase(Locale.US).equals(this.getFalseBooleanValue(database).toLowerCase(Locale.US))) {\n                returnValue = this.getFalseBooleanValue(database);\n            } else if (database instanceof PostgresDatabase && Pattern.matches(\"b?([01])\\\\1*(::bit|::\\\"bit\\\")?\", (String) value)) {\n                returnValue = \"b'\"\n                    + value.toString()\n                    .replace(\"b\", \"\")\n                    .replace(\"\\\"\", \"\")\n                    .replace(\"::it\", \"\")\n                    + \"'::\\\"bit\\\"\";\n            } else {\n                throw new UnexpectedLiquibaseException(\"Unknown boolean value: \" + value);\n            }\n        } else if (value instanceof Long) {\n            if (Long.valueOf(1).equals(value)) {\n                returnValue = this.getTrueBooleanValue(database);\n            } else {\n                returnValue = this.getFalseBooleanValue(database);\n            }\n        } else if (value instanceof Number) {\n            if (value.equals(1) || \"1\".equals(value.toString()) || \"1.0\".equals(value.toString())) {\n                returnValue = this.getTrueBooleanValue(database);\n            } else {\n                returnValue = this.getFalseBooleanValue(database);\n            }\n        } else if (value instanceof DatabaseFunction) {\n            return value.toString();\n        } else if (value instanceof Boolean) {\n            if (((Boolean) value)) {\n                returnValue = this.getTrueBooleanValue(database);","sourceCodeStart":67,"sourceCodeEnd":103,"githubUrl":"https://github.com/YunaiV/ruoyi-vue-pro/blob/0418084e222612af2fc1141f566af454f9236ab1/sql/dm/flowable-patch/src/main/java/liquibase/datatype/core/BooleanType.java#L67-L103","documentation":"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.","triggerScenarios":"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.","commonSituations":"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'.","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."],"exampleFix":"// before\n<column name=\"active\" type=\"BOOLEAN\" defaultValue=\"Y\"/>\n// after\n<column name=\"active\" type=\"BOOLEAN\" defaultValueBoolean=\"true\"/>","handlingStrategy":"validation","validationCode":"private static final Pattern BOOL = Pattern.compile(\"^(true|false|0|1|b'0|b'1|t|f)$\", Pattern.CASE_INSENSITIVE);\nif (value instanceof String && !BOOL.matcher(((String)value)).matches()) {\n    throw new IllegalArgumentException(\"Unrecognized boolean literal: \" + value);\n}","typeGuard":"static boolean isLiquibaseBooleanLiteral(Object v) {\n    if (!(v instanceof String)) return false;\n    String s = ((String)v).toLowerCase(Locale.US);\n    return s.equals(\"true\") || s.equals(\"false\") || s.equals(\"0\") || s.equals(\"1\") || s.equals(\"f\") || s.equals(\"b'0\") || s.equals(\"b'1\");\n}","tryCatchPattern":"try {\n    return booleanType.objectToSql(value, db);\n} catch (UnexpectedLiquibaseException e) {\n    return \"0\"; // safe default, logged\n}","preventionTips":["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"],"tags":["liquibase","boolean","datatype-conversion","data-migration"],"backgroundTag":null,"analyzedSha":"0418084e222612af2fc1141f566af454f9236ab1","analyzedAt":"2026-08-14T00:56:18.412Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}