How does modifyChangeSets work with preconditions?
Last updated: June 9, 2026
In Liquibase 5.2 and later, you can use preconditions with modifyChangeSets to conditionally include or skip entire groups of changesets in XML, YAML, and JSON changelogs. This page explains how preconditions work in the context of modifyChangeSets and provides syntax examples.
Important notes
In Liquibase 5.2+,
CONTINUEandMARK_RANare now supported insidemodifyChangeSetspreconditions. These values were previously only supported at the changeset level.For the full list of
onFailandonErrorvalues and their behavior, see What are preconditions?.
How it works
When you add a preConditions block inside modifyChangeSets, Liquibase evaluates the precondition before processing any changesets in the include or includeAll entries nested under that modifyChangeSets block. Changesets inside modifyChangeSets are subject to the precondition. Changesets outside it, such as a top-level include entry, are not affected.
If a changeset already has its own preConditions block, the modifyChangeSets precondition is not applied to that changeset. The changeset-level precondition takes priority.
Precondition attributes
The preConditions element within modifyChangeSets supports the same attributes as changeset-level preconditions.
onFail values
Value | Description |
|---|---|
| Skips the changeset. Execution is attempted again on the next update. Continues with the changelog. |
| Halts execution of the entire changelog. This is the default. |
| Skips the changeset but marks it as executed in DATABASECHANGELOG. The changeset is not attempted again on subsequent updates. |
| Logs a warning and executes the changeset anyway. |
onError values
Value | Description |
|---|---|
| Skips the changeset on precondition error. |
| Halts execution on precondition error. This is the default. |
| Marks the changeset as executed on error without running it. |
| Logs a warning and continues on precondition error. |
Changeset-level precondition override
If a changeset in an included file already has its own preConditions element, the modifyChangeSets precondition is not applied to that changeset—the changeset-level precondition takes priority. This lets you set a default precondition for a group of changesets while allowing individual changesets to override it.
In the example below, mixed-changes is included inside a modifyChangeSets block that applies an Oracle precondition. The pg-only changeset has its own PostgreSQL precondition and ignores the modifyChangeSets one. The oracle-only changeset has no precondition and inherits the Oracle precondition from modifyChangeSets.
Combining with other modifyChangeSets attributes
Preconditions can be used alongside existing modifyChangeSets attributes like runWith, endDelimiter, and stripComments. In the example below, PostgreSQL SQL files are run with psql and only on PostgreSQL databases.
Backward compatibility
Existing modifyChangeSets blocks without preConditions continue to work exactly as before. Adding preConditions is optional and does not affect the behavior of modifyChangeSets blocks that do not use it.
Known limitations
When a changeset is skipped via a
modifyChangeSetsprecondition withonFail=CONTINUE, the UPDATE SUMMARY does not reflect the skipped changeset. The changeset is correctly not executed, but the Filtered out count in the summary remains 0.The
update-sqlcommand generates SQL for all changesets regardless of preconditions, because preconditions are evaluated at runtime against a live database.