{"record":{"id":"8f46d51498207a79","repo":"instructure/canvas-lms","slug":"missing-required-parameter-param-name-lti-asset-processor","errorCode":null,"errorMessage":"Missing required parameter: #{param_name}","messagePattern":"Missing required parameter: #(.+?)","errorType":"validation","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"app/models/lti/pns/lti_asset_processor_submission_notice_builder.rb","lineNumber":44,"sourceCode":"        assignment\n        asset_report_service_url\n        assets\n        custom\n        for_user_id\n        notice_event_timestamp\n        submission_lti_id\n      ].freeze\n      REQUIRED_ASSETS_PARAMS = %i[asset_id url sha256_checksum timestamp size content_type].freeze\n\n      def initialize(params)\n        validate_params!(params)\n        @params = params\n        super()\n      end\n\n      def validate_params!(params)\n        REQUIRED_PARAMS.each do |param_name|\n          raise ArgumentError, \"Missing required parameter: #{param_name}\" unless params[param_name]\n        end\n        params[:assets].each do |asset|\n          REQUIRED_ASSETS_PARAMS.each do |asset_param_name|\n            raise ArgumentError, \"Missing required asset parameter #{asset_param_name}\" unless asset[asset_param_name]\n          end\n        end\n      end\n\n      def notice_type\n        Lti::Pns::NoticeTypes::ASSET_PROCESSOR_SUBMISSION\n      end\n\n      def custom_ims_claims(_tool)\n        {\n          for_user: {\n            user_id: @params[:for_user_id],\n          },\n          assetreport: {","sourceCodeStart":26,"sourceCodeEnd":62,"githubUrl":"https://github.com/instructure/canvas-lms/blob/1c9f0bb8013ed69c4f2efe11fd483025469b7e6c/app/models/lti/pns/lti_asset_processor_submission_notice_builder.rb#L26-L62","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Read the REQUIRED_PARAMS constant and pass every listed key to the builder's constructor.","Ensure params[:assets] is a non-empty collection of asset hashes before constructing the builder.","Guard the call site: skip building the notice (or re-enqueue) when required data is unavailable instead of constructing with a partial hash.","Check for recent renames of the params keys between caller and builder."],"exampleFix":"// before\nLti::Pns::LtiAssetProcessorSubmissionNoticeBuilder.new(course: course, assets: nil)\n// after\nraise 'no assets' if assets.blank?\nLti::Pns::LtiAssetProcessorSubmissionNoticeBuilder.new(course: course, assets: assets)","handlingStrategy":"validation","validationCode":"REQUIRED = Lti::Pns::LtiAssetProcessorSubmissionNoticeBuilder::REQUIRED_PARAMS\nmissing = REQUIRED.select { |k| params[k].blank? }\nraise ArgumentError, \"missing #{missing.inspect}\" if missing.any? || params[:assets].blank?","typeGuard":null,"tryCatchPattern":"begin\n  Lti::Pns::LtiAssetProcessorSubmissionNoticeBuilder.new(params)\nrescue ArgumentError => e\n  Rails.logger.warn(\"PNS notice skipped: #{e.message}\")\n  nil\nend","preventionTips":["Mirror REQUIRED_PARAMS checks in the caller before enqueueing notice-build jobs","Never pass nil for optional-ish keys; omit or default them explicitly","Add factory/test helpers that construct valid param hashes for this builder"],"tags":["ruby","lti","argument-error","validation"],"backgroundTag":"missing-required-argument","analyzedSha":"1c9f0bb8013ed69c4f2efe11fd483025469b7e6c","analyzedAt":"2026-09-15T20:33:18.891Z","contentChangedAt":"2026-09-15T20:33:18.891Z","schemaVersion":2},"datasetVersion":"2026-09-23T02:17:17.105Z"}