{"record":{"id":"fd78f94d75d280d7","repo":"YunaiV/yudao-cloud","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/yudao-cloud/blob/477be9dd49ab7223a972a6abdff0684d6423dec3/sql/dm/flowable-patch/src/main/java/liquibase/datatype/core/BooleanType.java#L67-L103","documentation":"Liquibase BooleanType.objectToSqlValue fails to recognize the given value as a boolean. String values are matched against 'true'/'false', '1'/'0', \"b'0'\"/'f' (case-insensitive) and the database's native true/false literals; anything else reaches the final else branch and throws UnexpectedLiquibaseException.","triggerScenarios":"A changeset column default value or <constraints> boolean value passes a string that is not in the accepted set, e.g. defaultValue=\"yes\", defaultValue=\"Y\", defaultValueComputed misused for a plain string, or a dialect-specific literal (e.g. \"t\"' or \"TRUE()\") that the current database's getTrueBooleanValue() does not return.","commonSituations":"Porting a changelog written for one database (MySQL '1'/'0', PostgreSQL bit strings) to another (DM/Oracle expecting 'TRUE'/'FALSE' or 1/0); XML changelogs where defaultValueComputed is used instead of defaultValue; locale-specific or quoted literals like \"'true'\" (extra quotes).","solutions":["Use a canonical boolean string in the changeset: 'true'/'false', '1'/'0', or exactly the value the target database's getTrueBooleanValue()/getFalseBooleanValue() returns.","Remove extra quotes/whitespace — pass true, not 'true' with embedded quotes.","If the value is computed SQL, move it to defaultValueComputed instead of defaultValue.","For database-specific literals, set the value in a changeset property conditioned per-database (context/dbms attribute)."],"exampleFix":"<!-- before -->\n<column name=\"active\" type=\"boolean\" defaultValue=\"yes\"/>\n\n<!-- after -->\n<column name=\"active\" type=\"boolean\" defaultValue=\"true\"/>","handlingStrategy":"validation","validationCode":"private static final Pattern OK = Pattern.compile(\"(?i)^(true|false|1|0|b'[01]'|t|f)$\");\nString v = String.valueOf(defaultValue).trim();\nif (!OK.matcher(v).matches()) throw new IllegalArgumentException(\"Bad boolean literal: \" + v);","typeGuard":"boolean isLiquibaseBoolean(Object v) {\n    return v instanceof Boolean || v instanceof Number\n        || (v instanceof String s && s.matches(\"(?i)(true|false|1|0|b'[01]'|t|f)\"));\n}","tryCatchPattern":"try { value = BooleanType.objectToSqlValue(raw, db); }\ncatch (UnexpectedLiquibaseException e) {\n    if (e.getMessage().startsWith(\"Unknown boolean value\")) value = raw == null ? null : String.valueOf(raw);\n    else throw e;\n}","preventionTips":["Normalize boolean defaults to 'true'/'false' or '1'/'0' at the edge of changelog generation","Lint changelog XML for defaultValue attributes outside the accepted literal set in CI"],"tags":["liquibase","boolean","datatype","changelog","migration"],"backgroundTag":null,"analyzedSha":"477be9dd49ab7223a972a6abdff0684d6423dec3","analyzedAt":"2026-08-14T13:35:31.121Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}