Skip to content

Fix Liquibase Context Filter – Changeset Not Running in Context

DodaTech Updated 2026-06-24 3 min read

In this tutorial, you'll learn about Fix Liquibase Context Filter. We cover key concepts, practical examples, and best practices.

You add a context attribute to a changeset to limit it to development only. You run liquibase update with the dev context — and the changeset is skipped. Or you run without the dev context and it runs anyway.

Wrong ❌

# db/changelog-master.yaml
databaseChangeLog:
  - changeSet:
      id: seed-dev-data
      author: alice
      context: dev          # ❌ should be "dev" (lowercase string)
      changes:
        - insert:
            tableName: users
            row:
              - column:
                  name: name
                  value: Dev User

```bash
liquibase --contexts=dev update

Output:

No changes found.

The changeset with `context: dev` is skipped even though you passed `--contexts=dev`.

## Right ✅

```yaml
# db/changelog-master.yaml
databaseChangeLog:
  - changeSet:
      id: seed-dev-data
      author: alice
      context: "dev"                      # quoted — good practice
      changes:
        - insert:
            tableName: users
            column:
              name: name
              value: Dev User

  - changeSet:
      id: create-prod-index
      author: alice
      context: "!dev"                     # NOT in dev — runs in staging/prod
      changes:
        - createIndex:
            tableName: users
            indexName: idx_users_email_prod

```bash
# Run with dev context
liquibase --contexts=dev update
# Applies: seed-dev-data
# Skips:   create-prod-index

# Run with prod context
liquibase --contexts=prod update
# Skips:   seed-dev-data
# Applies: create-prod-index

# Run with no context
liquibase update
# Skips both (neither has an empty context)

**Multiple contexts:**

```yaml
context: "dev OR staging"        # runs in dev OR staging
context: "dev AND staging"       # runs only when both are active
context: "dev,staging"           # same as OR (comma-separated)

**CLI context selection:**

```bash
liquibase --contexts=dev,staging update
# Applies: "dev", "staging", "dev OR staging", "dev AND staging" (if both)

**Check which contexts are active:**

```bash
liquibase --contexts=dev status --verbose
# Shows: Changeset 'seed-dev-data' will be applied (context: dev)

**Contexts in XML:**

```xml
<changeSet id="seed-dev-data" author="alice" context="dev">
  <insert tableName="users">
    <column name="name" value="Dev User"/>
  </insert>
</changeSet>

**If a changeset runs when it shouldn't — verify the context spelling:**

```yaml
context: "Development"          # ❌ mismatch with CLI --contexts=dev
context: "dev"                  # ✅

## Root Cause

Context matching is case‑sensitive and evaluates `AND`/`OR`/`!` operators. A spelling mismatch between the changeset's `context` and the CLI's `--contexts` causes the changeset to be skipped. Using `!context` (NOT) can lead to unexpected execution.

## Prevention

- Use lowercase context names consistently.
- Test with `liquibase status --verbose` to see which changesets will run.
- Use `AND` sparingly — it's easy to forget one context.
- Keep contexts in a documentation file so the team knows which values to use.


## Common Mistakes with context filter

1. **Placing the wildcard pattern first in case expressions, making all subsequent patterns unreachable**
2. **Using `head` and `tail` instead of pattern matching, causing runtime errors on empty lists**
3. **Forgetting that lazy evaluation defers computation until the value is forced, causing space leaks with unevaluated thunks**

These mistakes appear frequently in real-world LIQUIBASE code. DodaTech's contributors have identified these patterns through analysis of open-source projects and production systems.

## Practice Exercise

**Write a pure function that safely divides two integers using Maybe, then test it with edge cases like division by zero and negative numbers.**

This exercise reinforces the concepts covered in this guide. Try implementing it before checking online solutions.

## FAQ

<details style="margin-bottom:12px;border:1px solid #e2e8f0;border-radius:10px;overflow:hidden"><summary style="cursor:pointer;padding:14px 18px;font-weight:600;font-size:1.05rem;background:#f8fafc;border-bottom:1px solid #e2e8f0;color:#1e293b">**Q: Can I use context with SQL changelogs?**</summary><div style="padding:14px 18px;color:#475569;line-height:1.7;background:#fff"><p>A: Yes — annotate the <code>&lt;changeSet&gt;</code> with <code>context</code>, even when using <code>&lt;sql&gt;</code>.</p>
</div></details><details style="margin-bottom:12px;border:1px solid #e2e8f0;border-radius:10px;overflow:hidden"><summary style="cursor:pointer;padding:14px 18px;font-weight:600;font-size:1.05rem;background:#f8fafc;border-bottom:1px solid #e2e8f0;color:#1e293b">**Q: What's the default context if not specified?**</summary><div style="padding:14px 18px;color:#475569;line-height:1.7;background:#fff"><p>A: No context — the changeset always runs (unless filtered by <code>--contexts</code>).</p>
</div></details><details style="margin-bottom:12px;border:1px solid #e2e8f0;border-radius:10px;overflow:hidden"><summary style="cursor:pointer;padding:14px 18px;font-weight:600;font-size:1.05rem;background:#f8fafc;border-bottom:1px solid #e2e8f0;color:#1e293b">**Q: Can I use context with labels instead?**</summary><div style="padding:14px 18px;color:#475569;line-height:1.7;background:#fff"><p>A: Labels are similar but evaluated differently. Contexts use boolean expressions; labels are simpler.</p>
</div></details><details style="margin-bottom:12px;border:1px solid #e2e8f0;border-radius:10px;overflow:hidden"><summary style="cursor:pointer;padding:14px 18px;font-weight:600;font-size:1.05rem;background:#f8fafc;border-bottom:1px solid #e2e8f0;color:#1e293b">**Q: How do I run a changeset that has NO context?**</summary><div style="padding:14px 18px;color:#475569;line-height:1.7;background:#fff"><p>A: Run without <code>--contexts</code> or remove the context attribute from the changeset.</p>
</div></details>

---

*Context filtering is covered in the [DodaTech Liquibase Environments course](https://dodatech.com/courses/liquibase).*

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro