flippercloud/flipper · error · RuntimeError

Your database needs to be migrated to use the latest Flipper

Error message

Your database needs to be migrated to use the latest Flipper features.
Run `rails generate flipper:update` and `rails db:migrate`.

What it means

The ActiveRecord adapter stores JSON-typed gate values (feature expressions) in the flipper_gates.value column, which must be a :text column of unlimited length. Before writing a JSON gate, set() checks value_not_text? (column_for_attribute(:value).type != :text, see PR #692) and raises VALUE_TO_TEXT_WARNING when the schema is still the old string/varchar shape. The adapter refuses to write rather than risk truncated/corrupt JSON. Reads of every other gate type keep working, so the error only surfaces once code starts enabling expression (JSON) gates.

Source

Thrown at lib/flipper/adapters/active_record.rb:211

      def unsupported_data_type(data_type)
        raise "#{data_type} is not supported by this adapter"
      end

      private

      def model_class(default_class, table_prefix, table_name)
        return default_class if table_prefix.nil?

        Class.new(default_class) do
          self.table_name = "#{table_prefix}#{table_name}"
        end
      end

      def set(feature, gate, thing, options = {})
        clear_feature = options.fetch(:clear, false)
        json_feature = options.fetch(:json, false)

        raise VALUE_TO_TEXT_WARNING if json_feature && value_not_text?

        with_write_connection(@gate_class) do
          @gate_class.transaction(requires_new: true) do
            clear(feature) if clear_feature
            delete(feature, gate)
            begin
              @gate_class.create! do |g|
                g.feature_key = feature.key
                g.key = gate.key
                g.value = json_feature ? Typecast.to_json(thing.value) : thing.value.to_s
              end
            rescue ::ActiveRecord::RecordNotUnique
              # assume this happened concurrently with the same thing and its fine
              # see https://github.com/flippercloud/flipper/issues/544
            end
          end
        end

View on GitHub (pinned to 1f86de3ec9)

Solutions

  1. Run `rails generate flipper:update && rails db:migrate` in the affected environment — this migrates flipper_gates.value to text.
  2. Do the same for test/CI databases (`rails db:test:prepare` or RAILS_ENV=test rails db:migrate) so specs do not hit the old schema.
  3. Verify the fix: check the column type via ActiveRecord::Base.connection.columns(:flipper_gates) and confirm the `value` column reports :text.
  4. If it still raises after migrating, check that the adapter was not built with a custom gate_class or table_prefix that points at a different, unmigrated gates table.

Example fix

# before
Flipper.enable_expression(:search, Flipper.property(:plan).eq("pro"))
# => RuntimeError: Your database needs to be migrated to use the latest Flipper features.

# after — run once per environment
# rails generate flipper:update
# rails db:migrate
Flipper.enable_expression(:search, Flipper.property(:plan).eq("pro")) # works
Defensive patterns

Strategy: validation

Validate before calling

def flipper_gates_value_is_text?
  column = ActiveRecord::Base.connection.columns(:flipper_gates).find { |c| c.name == "value" }
  column&.type == :text
end

raise "Run rails generate flipper:update && rails db:migrate before enabling expressions" unless flipper_gates_value_is_text?

Try / catch

begin
  Flipper.enable_expression(:search, expr)
rescue RuntimeError => e
  raise unless e.message.include?("rails generate flipper:update")
  # block expression usage until the migration ships
end

Prevention

When it happens

Trigger: feature.enable_expression / Flipper.enable_expression(...), feature.add_expression, or any write whose gate data_type is :json (set(..., json: true)) — including the cache_write path — against a database where flipper_gates.value is still string/varchar instead of text.

Common situations: Upgrading flipper-active_record to a version with expression gates without running the new migration; a long-lived app whose flipper tables were generated years ago; CI or staging databases restored from an old schema dump; deploying code that uses Flipper expressions before the flipper:update migration has run in that environment; a custom gate_class/table_prefix pointing at a table nobody migrated.

Related errors


AI-assisted analysis of flippercloud/flipper@1f86de3ec9 (2026-08-23). Data as JSON: /api/errors/648b33a20267ce41. Report an issue: GitHub.