Skip to content
Latchkey

Ruby RuboCop Version Mismatch Fails Lint in CI

RuboCop in CI is a different version than the one developers run locally, so it enforces a different set of cops and defaults. New offenses appear (or .rubocop.yml references cops the CI version does not know), failing lint.

What this error means

rubocop passes on a developer machine but fails in CI with offenses no one changed, or with "unrecognized cop" / "obsolete parameter" errors from .rubocop.yml. The code did not change behavior - the RuboCop version did.

rubocop output
Error: unrecognized cop or department Style/RedundantStringEscape found in
.rubocop.yml
# or
841 files inspected, 17 offenses detected
# (offenses only the newer rubocop version flags)

Common causes

CI RuboCop version differs from local

A globally installed or unpinned RuboCop in CI differs from the locked one developers use. New cops/defaults flag offenses, or removed cops in config error out.

rubocop config references cops from another version

.rubocop.yml enables or configures a cop that exists in one RuboCop version but not the version running in CI, producing config errors.

How to fix it

Pin RuboCop and run it through Bundler

Lock RuboCop (and its extension gems) in the Gemfile and invoke via bundle exec so local and CI match.

Gemfile / Terminal
# Gemfile
gem 'rubocop', '1.65.0', require: false
# CI / local
bundle exec rubocop

Keep config and version in lockstep

  1. Bump RuboCop and update .rubocop.yml together in one PR.
  2. Run bundle exec rubocop everywhere - never a globally installed rubocop.
  3. Pin rubocop extension gems (rubocop-rails, rubocop-rspec) to compatible versions.

How to prevent it

  • Pin RuboCop and its extensions in the Gemfile and commit the lock.
  • Always run bundle exec rubocop, never a global install.
  • Update the RuboCop version and config in the same change.

Related guides

Tired of flaky CI? Latchkey auto-heals failed jobs and retries them for you. Start free →