Migrating the Ruby SDK for Featurevisor v4
- Minimal migration path
- Breaking changes
- Plain Date inputsBreaking
- Root condition reasonBreaking
- Datafile update resultBreaking
- Replace removed module hooksBreaking
- Update detailed evaluation fieldsBreaking
- Number getterBreaking
- OpenFeature
- Migration checklist
Upgrade Ruby applications to SDK 4.0.0 for Featurevisor v4 support.
Follow the shared migration order: prepare canonical prerequisite datafiles, upgrade consumers, then upgrade the project CLI. Before publishing new runtime fields, follow Adopt new syntax safely.
Convert Groups before upgrading
This SDK silently ignores legacy feature ranges, with no compatibility handling or warning. Convert Groups to flat list requirements while still on the previous compatible SDK and v3 CLI, then publish all datafiles, caches and bundled copies before upgrading. Unconverted files can change cohorts or enable features without a variation. Old cohorts are not guaranteed. Follow Groups removed.
Minimal migration path#
- Prepare existing feature prerequisites using the central migration order.
- Replace the removed module hooks and detailed evaluation fields below if your application uses them.
- Upgrade the base gem to 4.0.0. If the application uses the OpenFeature gem, upgrade it at the same time.
- Follow the mixed version deployment guidance before enabling any new v4 datafile capability.
Most application source code can stay unchanged after datafile preparation. The factory, standard getters, child instances, sticky setters and separate evaluation snapshots keep their existing names:
f = Featurevisor.create_featurevisor(datafile: datafile)enabled = f.is_enabled('checkout', context)variation = f.get_variation('checkout', context)label = f.get_variable('checkout', 'label', context)support_email = f.get_variable('supportEmail', context)f.set_sticky_features(sticky_features)f.set_sticky_variables(sticky_variables)feature_evaluations = f.get_feature_evaluationsvariable_evaluations = f.get_variable_evaluationschild = f.spawn({ country: 'nl' })There is no sticky API or snapshot API rename to perform for these canonical methods.
Breaking changes#
Plain Date inputs Breaking#
A plain Ruby Date has no time or offset and is no longer accepted by before or after. Both comparisons return false, which a surrounding not may invert. Replace it with an explicit instant, using Time, DateTime or a portable timestamp string:
context = { now: Date.new(2026, 1, 1) }context = { now: Time.utc(2026, 1, 1) }Choose the intended timezone explicitly rather than relying on the server's local timezone.
Root condition reason Breaking#
An unmet root gate reports conditions_unmet for feature flags and global variables, replacing the v3 required reason for feature flags and required_features_unmet for global variables. This applies to attribute, segment, feature and variable leaves in root conditions. Update callbacks, analytics and test expectations. Variation and feature variable evaluations retain their disabled reasons. See the shared migration guidance.
unmet_requirement = evaluation[:reason] == "required"unmet_requirement = evaluation[:reason] == "conditions_unmet"Datafile update result Breaking#
set_datafile now returns true when it accepts the update, including unchanged content, and false when it rejects the update or the instance is closed. A rejected update keeps the previous datafile and reports details through diagnostics. Calls that ignore the result keep working. Update any wrapper or interface that declares the old return type. Merging remains the default.
f.set_datafile(datafile)accepted = f.set_datafile(datafile)unless accepted warn 'Datafile rejected. Check diagnostics.'endReplace removed module hooks Breaking#
The old before and after module hooks are removed. Use before_evaluation and after_evaluation, which already existed in the previous SDK line and are now the only evaluation hooks.
my_module = { name: 'application-module', before: ->(options) { options }, after: ->(evaluation, options) { evaluation }}f = Featurevisor.create_featurevisor( datafile: datafile, modules: [my_module])my_module = { name: 'application-module', before_evaluation: ->(options) { options }, after_evaluation: ->(evaluation, options) { evaluation }}f = Featurevisor.create_featurevisor( datafile: datafile, modules: [my_module])The canonical hooks also run for global variable evaluation. If a module contains feature specific behaviour, guard it with options.key?(:feature_key).
Update detailed evaluation fields Breaking#
Only code that reads detailed evaluation hashes needs these changes:
| Before | After |
|---|---|
evaluation[:required] | evaluation[:conditions] |
evaluation[:sticky] | evaluation[:sticky_feature] |
New variable prerequisite failures are exposed through evaluation[:conditions]. Ordinary getter return types do not change.
Number getter Breaking#
Variables that hold numbers have the type number, so the typed getter is now get_variable_number. It reads number variables and the double variables of datafiles built before v4. get_variable_double was removed. Rename calls to the number getter, which returns the same value.
threshold = f.get_variable_double("freeShippingThreshold", context)threshold = f.get_variable_number("freeShippingThreshold", context)OpenFeature #
The Ruby OpenFeature provider remains in the separate featurevisor-openfeature gem, which requires the matching base featurevisor gem. If your application uses the provider, upgrade both gems to 4.0.0. The updated provider maps conditions_unmet to OpenFeature's disabled reason.
An empty targeting key received by the provider now replaces an existing userId or configured targeting field with "". An omitted key preserves that field. Verify the final context delivered by your OpenFeature client when contexts are merged.
See the Ruby SDK OpenFeature guide for provider setup.
Migration checklist#
Required for the migration#
- Confirm every consumer uses a compatible SDK release and that existing prerequisites use
conditionsandfeature. - Confirm no module still declares
beforeorafter, and detailed evaluation readers use the canonical fields. - Rename
get_variable_doublecalls toget_variable_number. - Upgrade the project CLI last, review mutation order and date and regex comparisons, and retain a prepared rollback datafile.
Only if adopting optional features#
Follow Adopt new syntax safely before publishing new datafile syntax. Upgrade every CLI runner before adding checks or scenarios.

