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

Unsupported type_cast `#

Error message

Unsupported type_cast `#{type_cast}` for setting `#{setting_name}`

What it means

CanvasOperations::Errors::InvalidTypeCast raised by the else branch of validate_type_cast!: the type_cast argument is neither a Symbol nor a Proc. Only those two forms are supported for converting the raw String Setting value.

Solutions

  1. Use a Symbol (e.g. :to_i) or a one-argument Proc for type_cast
  2. Convert a String cast name to a symbol: type_cast.to_sym (after verifying it's a valid String method)
  3. Remove the type_cast option to accept the default :to_s behavior

Example fix

// before
setting(:limit, default: 10, type_cast: 'to_i')
// after
setting(:limit, default: 10, type_cast: :to_i)
Defensive patterns

Strategy: type-guard

Validate before calling

raise 'type_cast must be Symbol or Proc' unless type_cast.is_a?(Symbol) || type_cast.is_a?(Proc)

Type guard

def valid_type_cast?(tc)
  tc.is_a?(Symbol) || tc.is_a?(Proc)
end

Try / catch

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

Prevention

When it happens

Trigger: Passing type_cast: 'to_i' (a String), type_cast: Integer, a class, or an array as the type_cast option to setting.

Common situations: Quoting the symbol by accident; passing a class like Float instead of the symbol :to_f; dynamically computed cast values that end up nil or a string.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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

Appendix: source

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

          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)