instructure/canvas-lms · error · Errors::InvalidTypeCast

Unsupported type_cast `#

Error message

Unsupported type_cast `#{type_cast}` for setting `#{setting_name}`. #{SETTINGS_TYPE_INSTANCE.class} does not respond to `#{type_cast}`.

What it means

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).

Solutions

  1. Use a String-built-in cast symbol like :to_i, :to_f, or :to_s
  2. Define the missing method on String (monkey patch/extension) if a custom cast is needed
  3. Use a Proc instead: type_cast ->(s) { Integer(s) }

Example fix

// before
setting(:retries, default: 3, type_cast: :to_int)
// after
setting(:retries, default: 3, type_cast: :to_i)
Defensive patterns

Strategy: validation

Validate before calling

raise 'bad cast' unless type_cast.is_a?(Symbol) && ''.respond_to?(type_cast)

Try / catch

rescue CanvasOperations::Errors::InvalidTypeCast
  value = default
end

Prevention

When it happens

Trigger: setting(:name, default: 0, type_cast: :to_integer) where String has no :to_integer instance method; typos like :toInt.

Common situations: Porting casts from other frameworks (Integer(), Float()) as symbols; assuming app-specific monkey patches exist in every environment where the operation runs.

Related errors


AI-assisted analysis of instructure/canvas-lms@1c9f0bb801 (2026-09-15). Data as JSON: /api/errors/385a63267fddd59a. Report an issue: GitHub.

Appendix: source

Thrown at lib/canvas_operations/base_concerns/settings.rb:129

        define_singleton_method("set_#{setting_name}_for_cluster") do |value, cluster:|
          modify_setting_for(setting_name, value, cluster:)
        end

        # Convenience protected instance methods for accessing settings
        #
        # Always returns the setting for the operation's current shard's cluster.
        define_method(setting_name) do
          self.class.send(setting_name, cluster:)
        end
        protected setting_name
      end

      def validate_type_cast!(type_cast, setting_name)
        case type_cast
        when Symbol
          # Setting values are always Strings, so ensure the type_cast method exists on String
          unless SETTINGS_TYPE_INSTANCE.respond_to?(type_cast)
            raise Errors::InvalidTypeCast,
                  "Unsupported type_cast `#{type_cast}` for setting `#{setting_name}`. #{SETTINGS_TYPE_INSTANCE.class} does not respond to `#{type_cast}`."
          end
        when Proc
          unless type_cast.arity == 1
            raise Errors::InvalidTypeCast, "type_cast Proc must take exactly one argument for setting `#{setting_name}`"
          end
        else
          raise Errors::InvalidTypeCast, "Unsupported type_cast `#{type_cast}` for setting `#{setting_name}`"
        end
      end

      def settings_key(setting_name, cluster:)
        "clusters/#{cluster}/#{operation_name}/#{setting_name}"
      end
    end
  end
end

View on GitHub (pinned to 1c9f0bb801)