vacuum can detect changes between two versions of an OpenAPI specification and use that information to:

  • Filter linting results (only show violations in areas that have changed)
  • Inject violations (for any kind of changes)
  • Customize breaking change rules (match your organization’s policies)

This is particularly useful in CI/CD pipelines where you only want to see issues introduced by the current PR or commit.

Prerequisites

Change detection uses libopenapi’s what-changed module. This is configured in vacuum the same way that it’s configured in openapi-changes.

I am not going to duplicate the configuration details here as it’s all documented here.

Available Flags

Change detection flags are global persistent flags available on all commands that support linting: lint, report, html-report, spectral-report, and dashboard.

Full Description
–original string - Path to original/old spec file for inline comparison
–changes string - Path to pre-generated change report JSON file
–changes-summary bool - Show summary of what was filtered by --changes or --original
–breaking-config string - Path to breaking rules config file
–warn-on-changes bool - Inject warning violations for each detected API change
–error-on-breaking bool - Inject error violations for each breaking change

These flags have no shorthand versions. Environment variables are supported: VACUUM_ORIGINAL, VACUUM_CHANGES, etc.

Left / Right Comparison

The simplest approach is to provide the path to the original (left/old) specification. vacuum will compare it against the specification being linted and filter results to changed areas.

Use the --original flag.

vacuum lint new-api.yaml --original old-api.yaml -d

Using Change Reports

You can pre-generate a change report JSON file using openapi-changes and pass it to vacuum:

Use the --changes

vacuum lint new-api.yaml --changes change-report.json -d

Change filtering summary

Use --changes-summary to see what was filtered out of the results:

vacuum lint new-api.yaml --original old-api.yaml --changes-summary -d

This displays statistics about:

  • Total violations before/after filtering
  • Number of changes detected
  • Breaking vs non-breaking change counts

Injecting Change Violations

Beyond filtering, vacuum can inject violations for detected changes. This integrates change detection into your normal linting workflow.

Injecting changes as warnings

Use --warn-on-changes to create a warning violation for every detected API change:

vacuum lint new-api.yaml --original old-api.yaml --warn-on-changes -d

Each change appears as an api-change violation with severity warn.

Injecting errors on breaking

Use --error-on-breaking to create an error violation for every breaking change:

vacuum lint new-api.yaml --original old-api.yaml --error-on-breaking -d

Each breaking change appears as a breaking-change violation with severity error. This causes vacuum to return a non-zero exit code, failing your CI/CD pipeline.

Combining Both Flags

You can use both flags together to get warnings for non-breaking changes and errors for breaking changes:

vacuum lint new-api.yaml --original old-api.yaml \ --warn-on-changes --error-on-breaking -d

Breaking Change Configuration

By default, vacuum uses the same breaking change rules as openapi-changes, which is powered by libopenapi’s what-changed module You can customize which changes are considered breaking using a configuration file.

Configuration File Locations

vacuum automatically looks for breaking rules configuration in these locations:

  • ./changes-rules.yaml (current directory)
  • ~/.config/changes-rules.yaml (user config directory)

Or specify a custom path with --breaking-config:

vacuum lint new-api.yaml --original old-api.yaml \ --breaking-config my-rules.yaml --error-on-breaking

Configuration Format

The configuration format is identical to openapi-changes configuration. You only need to specify the rules you want to override, everything else uses defaults.

For example, allowing enum additions without treating them as breaking:

# changes-rules.yaml - sparse override example
schemaChanges:
  enum:
    added: false    # Adding enum values is NOT breaking
    modified: true  # Modifying enum values IS breaking
    removed: true   # Removing enum values IS breaking

allowing deprecation changes:

propertyChanges:
  deprecated:
    added: false    # Adding deprecated flag is NOT breaking
    modified: false # Changing deprecated flag is NOT breaking
    removed: true   # Removing deprecated IS breaking

For the complete list of configurable rules, see the openapi-changes configuration guide.

Multi-file Mode Limitation

Important: Change detection flags (--changes, --original) are ignored in multi-file mode when using --globbed-files. A warning will be displayed when this occurs.

For multi-file scenarios, run vacuum separately for each file with its corresponding original version.


LSP Integration

When using language-server, violations from --error-on-breaking and --warn-on-changes appear as diagnostics in your editor. Configure the language server with these flags to get real-time feedback on breaking changes as you edit.