instructure/canvas-lms · error · Lti::IMS::AdvantageErrors::InvalidLaunchError

Assignment not configured for external tool launches

Error message

Assignment not configured for external tool launches

What it means

assignment_resource_link in lib/lti/messages/resource_link_request.rb:104 raises Lti::IMS::AdvantageErrors::InvalidLaunchError when building an assignment resource link for an assignment that is not an external tool assignment. A resource link request can only be generated for assignments configured with an LTI tool, so non-tool assignments abort the launch.

Solutions

  1. Verify the assignment is created with submission_type 'external_tool' and points at the correct tool before launching
  2. Check that Lti::ToolFinder.from_assignment(assignment) matches the launching @tool if you expect a tool launch
  3. Rescue InvalidLaunchError and return a 4xx with the api_message instead of attempting the launch
  4. Recreate/fix the assignment's external tool configuration if it was changed incorrectly

Example fix

// before
ResourceLinkRequest.create(tool:, context:, assignment: plain_assignment, ...)
// after
raise InvalidLaunchError unless plain_assignment.external_tool?
ResourceLinkRequest.create(tool:, context:, assignment: plain_assignment, ...)
Defensive patterns

Strategy: validation

Validate before calling

raise InvalidLaunchError unless assignment.external_tool? && Lti::ToolFinder.from_assignment(assignment) == tool

Try / catch

begin
  resource_link = builder.assignment_resource_link
rescue Lti::IMS::AdvantageErrors::InvalidLaunchError => e
  render json: {error: e.api_message}, status: :bad_request
end

Prevention

When it happens

Trigger: Generating an LTI resource link request (AGS/Advantage launch) for @assignment that is not external_tool?; tool/assignment mismatch also raises with the 'launches with specified tool' message on the next check.

Common situations: LTI 1.3 launches triggered for ordinary canvas assignments; deep-linking or NRPS flows pointed at the wrong assignment id; a tool changed the assignment type after launch configuration.

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/f46cf0b5180ae340. Report an issue: GitHub.

Appendix: source

Thrown at lib/lti/messages/resource_link_request.rb:104

      resource_link&.resource_link_uuid || Lti::V1p1::Asset.opaque_identifier_for(@context)
    end

    def unexpanded_custom_parameters
      # Add in link-specific custom params (e.g. created by deep linking)
      super.merge(resource_link&.custom || {})
    end

    def resource_link
      assignment_resource_link || @opts[:resource_link]
    end

    def assignment_resource_link
      return if @assignment.nil?

      unless defined?(@assignment_resource_link)
        launch_error = Lti::IMS::AdvantageErrors::InvalidLaunchError
        unless @assignment.external_tool?
          raise launch_error.new(nil, api_message: "Assignment not configured for external tool launches")
        end
        unless Lti::ToolFinder.from_assignment(@assignment) == @tool
          raise launch_error.new(nil, api_message: "Assignment not configured for launches with specified tool")
        end

        @assignment_resource_link = line_item_for_assignment&.resource_link
      end

      @assignment_resource_link
    end

    def line_item_for_assignment
      @line_item_for_assignment ||= @assignment&.line_items&.find(&:assignment_line_item?)
    end

    # follows the spec at https://www.imsglobal.org/spec/lti-ags/v2p0/#assignment-and-grade-service-claim
    # and only adds the 'lineitem' property "when the LTI message is launching a resource associated
    # to one and only one line item"

View on GitHub (pinned to 1c9f0bb801)