instructure/canvas-lms · error · ArgumentError

Missing required parameter: #

Error message

Missing required parameter: #{param_name}

What it means

Lti::Pns::LtiAssetProcessorSubmissionNoticeBuilder validates its params hash in validate_params! (invoked from initialize) against REQUIRED_PARAMS. If any top-level key in REQUIRED_PARAMS is absent or falsy, it raises ArgumentError naming the missing parameter. This guarantees Platform Notification Service notices are never built with incomplete payloads.

Solutions

  1. Read the REQUIRED_PARAMS constant and pass every listed key to the builder's constructor.
  2. Ensure params[:assets] is a non-empty collection of asset hashes before constructing the builder.
  3. Guard the call site: skip building the notice (or re-enqueue) when required data is unavailable instead of constructing with a partial hash.
  4. Check for recent renames of the params keys between caller and builder.

Example fix

// before
Lti::Pns::LtiAssetProcessorSubmissionNoticeBuilder.new(course: course, assets: nil)
// after
raise 'no assets' if assets.blank?
Lti::Pns::LtiAssetProcessorSubmissionNoticeBuilder.new(course: course, assets: assets)
Defensive patterns

Strategy: validation

Validate before calling

REQUIRED = Lti::Pns::LtiAssetProcessorSubmissionNoticeBuilder::REQUIRED_PARAMS
missing = REQUIRED.select { |k| params[k].blank? }
raise ArgumentError, "missing #{missing.inspect}" if missing.any? || params[:assets].blank?

Try / catch

begin
  Lti::Pns::LtiAssetProcessorSubmissionNoticeBuilder.new(params)
rescue ArgumentError => e
  Rails.logger.warn("PNS notice skipped: #{e.message}")
  nil
end

Prevention

When it happens

Trigger: Calling Lti::Pns::LtiAssetProcessorSubmissionNoticeBuilder.new(params) where params omits any key listed in REQUIRED_PARAMS (e.g. missing :assets, or other required top-level keys), or passing an explicit nil for one of those keys.

Common situations: Job/enqueue code that builds PNS notices after an LTI Asset Processor submission was changed or deleted, so the asset data hash is nil; refactors that rename a params key without updating the builder call site; fixtures/tests passing partial hashes.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


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

Appendix: source

Thrown at app/models/lti/pns/lti_asset_processor_submission_notice_builder.rb:44

        assignment
        asset_report_service_url
        assets
        custom
        for_user_id
        notice_event_timestamp
        submission_lti_id
      ].freeze
      REQUIRED_ASSETS_PARAMS = %i[asset_id url sha256_checksum timestamp size content_type].freeze

      def initialize(params)
        validate_params!(params)
        @params = params
        super()
      end

      def validate_params!(params)
        REQUIRED_PARAMS.each do |param_name|
          raise ArgumentError, "Missing required parameter: #{param_name}" unless params[param_name]
        end
        params[:assets].each do |asset|
          REQUIRED_ASSETS_PARAMS.each do |asset_param_name|
            raise ArgumentError, "Missing required asset parameter #{asset_param_name}" unless asset[asset_param_name]
          end
        end
      end

      def notice_type
        Lti::Pns::NoticeTypes::ASSET_PROCESSOR_SUBMISSION
      end

      def custom_ims_claims(_tool)
        {
          for_user: {
            user_id: @params[:for_user_id],
          },
          assetreport: {

View on GitHub (pinned to 1c9f0bb801)