instructure/canvas-lms · error

Unsupported message type: #

Error message

Unsupported message type: #{message_type}

What it means

Lti::LaunchServices#build_jwt_message switches on the message type to pick a payload generator on the adapter; any message_type outside the explicitly supported list falls through to a generic RuntimeError. This guards the LTI Advantage JWT message pipeline against message types Canvas cannot build.

Solutions

  1. Add a when branch for the new message type mapping to the matching adapter generator method.
  2. Verify the message_type passed to build_jwt_message equals one of the supported LtiAdvantage::Messages::*::MESSAGE_TYPE constants.
  3. If a new type is needed, extend the LTI adapter with the corresponding generate_post_payload_for_* method.
  4. Rescue in create_and_log_launch and return 422/400 for unsupported types instead of a 500.

Example fix

// before
raise "Unsupported message type: #{message_type}"
// after
when LtiAdvantage::Messages::LineItemCreateRequest::MESSAGE_TYPE
  adapter.generate_post_payload_for_line_item
else
  raise "Unsupported message type: #{message_type}"
Defensive patterns

Strategy: validation

Validate before calling

SUPPORTED = LtiAdvantage::Messages.constants.map { |c| "LtiAdvantage::Messages::#{c}".constantize.try(:MESSAGE_TYPE) }
raise ArgumentError, message_type unless SUPPORTED.include?(message_type)

Type guard

def supported_message_type?(type)
  [LtiAdvantage::Messages::ReportReviewRequest::MESSAGE_TYPE,
   LtiAdvantage::Messages::EulaRequest::MESSAGE_TYPE].include?(type)
end

Try / catch

begin
  build_jwt_message(message_type, ...)
rescue RuntimeError => e
  raise UnsupportedMessageType, e.message if e.message.start_with?('Unsupported message type:')
  raise
end

Prevention

When it happens

Trigger: Calling create_and_log_launch with a message_type not in the case list (e.g. a custom or newly introduced LtiAdvantage::Messages::* type whose adapter generator branch was not added), or a mistyped/nil message_type string.

Common situations: Upgrading lti-advantage gem adds a new message type (e.g. a newer AGS/Proctoring type) before Canvas's launch service learns about it; plugins or custom code request an unregistered message type; typo in MESSAGE_TYPE constant.

Related errors


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

Appendix: source

Thrown at app/controllers/lti/launch_services.rb:73

      log_launch(
        message_type:,
        launch_type: log_launch_type,
        launch_url: lti_launch.params["target_link_uri"]
      )
      lti_launch
    end

    def build_jwt_message(adapter, message_type)
      case message_type
      when LtiAdvantage::Messages::AssetProcessorSettingsRequest::MESSAGE_TYPE
        adapter.generate_post_payload_for_asset_processor_settings
      when LtiAdvantage::Messages::ReportReviewRequest::MESSAGE_TYPE
        adapter.generate_post_payload_for_report_review
      when LtiAdvantage::Messages::EulaRequest::MESSAGE_TYPE
        adapter.generate_post_payload_for_eula
      else
        raise "Unsupported message type: #{message_type}"
      end
    end

    def create_lti_adapter(return_url:, lti_launch:, opts: {}, expander_opts: {})
      default_opts = {
        domain: HostUrl.context_host(@domain_root_account, request.host)
      }

      Lti::LtiAdvantageAdapter.new(
        tool:,
        user: @current_user,
        context:,
        return_url:,
        expander: create_variable_expander(lti_launch:, expander_opts:),
        include_storage_target: !in_lti_mobile_webview?,
        opts: default_opts.merge(opts)
      )
    end

View on GitHub (pinned to 1c9f0bb801)