{"record":{"id":"385a63267fddd59a","repo":"instructure/canvas-lms","slug":"unsupported-type-cast-type-cast-for-setting-setting-name","errorCode":null,"errorMessage":"Unsupported type_cast `#{type_cast}` for setting `#{setting_name}`. #{SETTINGS_TYPE_INSTANCE.class} does not respond to `#{type_cast}`.","messagePattern":"Unsupported type_cast `#(.+?)` for setting `#(.+?)`\\. #(.+?) does not respond to `#(.+?)`\\.","errorType":"validation","errorClass":"Errors::InvalidTypeCast","httpStatus":null,"severity":"error","filePath":"lib/canvas_operations/base_concerns/settings.rb","lineNumber":129,"sourceCode":"        define_singleton_method(\"set_#{setting_name}_for_cluster\") do |value, cluster:|\n          modify_setting_for(setting_name, value, cluster:)\n        end\n\n        # Convenience protected instance methods for accessing settings\n        #\n        # Always returns the setting for the operation's current shard's cluster.\n        define_method(setting_name) do\n          self.class.send(setting_name, cluster:)\n        end\n        protected setting_name\n      end\n\n      def validate_type_cast!(type_cast, setting_name)\n        case type_cast\n        when Symbol\n          # Setting values are always Strings, so ensure the type_cast method exists on String\n          unless SETTINGS_TYPE_INSTANCE.respond_to?(type_cast)\n            raise Errors::InvalidTypeCast,\n                  \"Unsupported type_cast `#{type_cast}` for setting `#{setting_name}`. #{SETTINGS_TYPE_INSTANCE.class} does not respond to `#{type_cast}`.\"\n          end\n        when Proc\n          unless type_cast.arity == 1\n            raise Errors::InvalidTypeCast, \"type_cast Proc must take exactly one argument for setting `#{setting_name}`\"\n          end\n        else\n          raise Errors::InvalidTypeCast, \"Unsupported type_cast `#{type_cast}` for setting `#{setting_name}`\"\n        end\n      end\n\n      def settings_key(setting_name, cluster:)\n        \"clusters/#{cluster}/#{operation_name}/#{setting_name}\"\n      end\n    end\n  end\nend\n","sourceCodeStart":111,"sourceCodeEnd":147,"githubUrl":"https://github.com/instructure/canvas-lms/blob/1c9f0bb8013ed69c4f2efe11fd483025469b7e6c/lib/canvas_operations/base_concerns/settings.rb#L111-L147","documentation":"CanvasOperations::Errors::InvalidTypeCast raised by validate_type_cast! when a Symbol type_cast is given but String does not respond to that method. Since Setting values are always Strings, the cast must be a method available on String (e.g. :to_i, :to_f, :to_bool wrappers).","triggerScenarios":"setting(:name, default: 0, type_cast: :to_integer) where String has no :to_integer instance method; typos like :toInt.","commonSituations":"Porting casts from other frameworks (Integer(), Float()) as symbols; assuming app-specific monkey patches exist in every environment where the operation runs.","solutions":["Use a String-built-in cast symbol like :to_i, :to_f, or :to_s","Define the missing method on String (monkey patch/extension) if a custom cast is needed","Use a Proc instead: type_cast ->(s) { Integer(s) }"],"exampleFix":"// before\nsetting(:retries, default: 3, type_cast: :to_int)\n// after\nsetting(:retries, default: 3, type_cast: :to_i)","handlingStrategy":"validation","validationCode":"raise 'bad cast' unless type_cast.is_a?(Symbol) && ''.respond_to?(type_cast)","typeGuard":null,"tryCatchPattern":"rescue CanvasOperations::Errors::InvalidTypeCast\n  value = default\nend","preventionTips":["Prefer String built-ins (:to_i, :to_f, :to_s) as cast symbols","Use a Proc for anything custom","Test settings-concern classes in every environment with different String extensions"],"tags":["ruby","type-cast","configuration","canvas-operations"],"backgroundTag":"unsupported-config-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"}