{"record":{"id":"6a505989090c8495","repo":"instructure/canvas-lms","slug":"datafixup-movefeatureflagstosettings-unable-to-handle","errorCode":null,"errorMessage":"DataFixup::MoveFeatureFlagsToSettings => unable to handle override state for context #{context.asset_string} of feature #{override.id} with state #{override.state}","messagePattern":"DataFixup::MoveFeatureFlagsToSettings => unable to handle override state for context #(.+?) of feature #(.+?) with state #(.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"lib/data_fixup/move_feature_flags_to_settings.rb","lineNumber":81,"sourceCode":"                 context.feature_flags.detect { |ff| ff.feature == feature_flag_name.to_s }\n               else\n                 context.feature_flags.find_by(feature: feature_flag_name.to_s)\n               end\n    override_value = nil\n    locked = true\n    if override\n      case override.state\n      when \"allowed\"\n        # no op\n      when \"allowed_on\"\n        override_value = true\n        locked = false\n      when \"on\"\n        override_value = true\n      when \"off\"\n        override_value = false\n      else\n        Rails.logger.warn(\"DataFixup::MoveFeatureFlagsToSettings => unable to handle override state for context \" \\\n                          \"#{context.asset_string} of feature #{override.id} with state #{override.state}\")\n      end\n    end\n\n    unless override_value.nil?\n      if context.is_a?(Account)\n        context.settings[setting_name] = inherited ? { locked:, value: override_value } : override_value\n      else\n        context.settings_frd[setting_name] = override_value\n      end\n      context.save!\n    end\n  end\n  private_class_method :figure_setting_from_override\nend\n","sourceCodeStart":63,"sourceCodeEnd":97,"githubUrl":"https://github.com/instructure/canvas-lms/blob/1c9f0bb8013ed69c4f2efe11fd483025469b7e6c/lib/data_fixup/move_feature_flags_to_settings.rb#L63-L97","documentation":"A warning logged by the DataFixup::MoveFeatureFlagsToSettings data fixup when it encounters a FeatureFlagOverride whose state is not one of 'on', 'off', or 'locked' that it can map to a value. The fixup cannot translate the override into the new settings storage, so it logs and skips that override rather than migrating it.","triggerScenarios":"Running the move_feature_flags_to_settings fixup over feature_flag_overrides rows containing a state value outside {'locked','on','off'} — typically stale, corrupted, or legacy rows written before the state enum was normalized.","commonSituations":"Long-lived production databases with overrides from old Canvas versions whose state strings were renamed or removed; manual DB edits or partial migrations leaving unexpected state values; running the fixup against a restored/partial dataset.","solutions":["Inspect the offending rows: SELECT * FROM feature_flag_overrides WHERE state NOT IN ('on','off','locked'); and decide the correct value per row.","Normalize the unexpected states to 'on'/'off'/'locked' (based on the feature's current behavior) and re-run the fixup.","If the state is genuinely meaningless (deleted feature/context), delete the orphan override row, then re-run the fixup.","Extend the fixup's case/when mapping if the new settings schema has a representation for that state."],"exampleFix":"// before\nUPDATE feature_flag_overrides SET state = 'on' WHERE state = 'allowed';\n// after\nUPDATE feature_flag_overrides SET state = 'on' WHERE state NOT IN ('on','off','locked');\n-- then re-run DataFixup::MoveFeatureFlagsToSettings.run","handlingStrategy":"validation","validationCode":"bad = FeatureFlagOverride.where.not(state: %w[on off locked])\nbad.find_each do |o|\n  Rails.logger.warn(\"un-migratable override: feature=#{o.feature} state=#{o.state}\")\nend","typeGuard":"def valid_override_state?(state)\n  %w[on off locked].include?(state)\nend","tryCatchPattern":"FeatureFlagOverride.find_each do |override|\n  unless %w[on off locked].include?(override.state)\n    next # or normalize before running the fixup\n  end\nend","preventionTips":["Audit feature_flag_overrides for non-standard state values before running fixups","Only mutate override state through AR validations/enums, never raw SQL","Run fixups in staging against a production snapshot first","Track skipped overrides (asset_string list) to reconcile after the run"],"tags":["data-fixup","feature-flags","migration","bad-enum-value"],"backgroundTag":"invalid-enum-value","analyzedSha":"1c9f0bb8013ed69c4f2efe11fd483025469b7e6c","analyzedAt":"2026-09-15T20:33:18.891Z","contentChangedAt":"2026-09-15T20:33:18.891Z","schemaVersion":2},"datasetVersion":"2026-09-23T02:17:17.105Z"}