{"record":{"id":"93e2bfc02ef02f44","repo":"instructure/canvas-lms","slug":"type-cast-proc-must-take-exactly-one-argument-for-setting","errorCode":null,"errorMessage":"type_cast Proc must take exactly one argument for setting `#{setting_name}`","messagePattern":"type_cast Proc must take exactly one argument for setting `#(.+?)`","errorType":"validation","errorClass":"Errors::InvalidTypeCast","httpStatus":null,"severity":"error","filePath":"lib/canvas_operations/base_concerns/settings.rb","lineNumber":134,"sourceCode":"        #\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":116,"sourceCodeEnd":147,"githubUrl":"https://github.com/instructure/canvas-lms/blob/1c9f0bb8013ed69c4f2efe11fd483025469b7e6c/lib/canvas_operations/base_concerns/settings.rb#L116-L147","documentation":"Guard in Canvas::Operations::BaseConcerns::Settings#validate_type_cast!: a type_cast declared as a Proc for a canvas operation setting does not take exactly one argument, so Errors::InvalidTypeCast is raised at definition time. It's a developer-facing config validation, not a runtime data error.","triggerScenarios":"setting(:x, default: 0, type_cast: ->(v, base=10) { v.to_i(base) }) or a zero-arg proc like type_cast: -> { nil }.","commonSituations":"Reusing multi-argument converters; lambda vs proc arity quirks when writing -> without parameters; wrapping methods that have optional extra params.","solutions":["Rewrite the Proc to take exactly one argument and bind other values via closure","Move extra conversion parameters into the closure body, not the signature","Use a simple Symbol cast if no custom logic is needed"],"exampleFix":"// before\nsetting(:port, default: 80, type_cast: ->(v, base) { v.to_i(base) })\n// after\nsetting(:port, default: 80, type_cast: ->(v) { v.to_i })","handlingStrategy":"validation","validationCode":"raise 'proc must take 1 arg' unless type_cast.is_a?(Proc) && type_cast.arity == 1","typeGuard":null,"tryCatchPattern":"rescue CanvasOperations::Errors::InvalidTypeCast\n  value = default\nend","preventionTips":["Write casts as single-parameter lambdas","Bind extra values via closure, not extra parameters","Remember proc {} has loose arity; prefer ->(v) { }"],"tags":["ruby","type-cast","proc","canvas-operations"],"backgroundTag":"invalid-argument-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"}