instructure/canvas-lms · error · ArgumentError

Missing required parameter: copied_at

Error message

Missing required parameter: copied_at

What it means

The same builder also requires params[:copied_at]; after the course check passes, initialize raises ArgumentError "Missing required parameter: copied_at" when that key is nil or missing. The timestamp of the copy is mandatory for the context-copy PNS notice payload.

Solutions

  1. Pass the copy completion time as params[:copied_at] (e.g. Time.now.utc or the recorded copy timestamp).
  2. Record the copied_at timestamp when the copy job starts/finishes and thread it through to the builder.
  3. Assert copied_at.present? before constructing the builder to fail with clearer context.
  4. Check for nil caused by serialization/deserialization of the job payload.

Example fix

// before
Lti::Pns::LtiContextCopyNoticeBuilder.new({ course: course })
// after
Lti::Pns::LtiContextCopyNoticeBuilder.new({ course: course, copied_at: Time.now.utc })
Defensive patterns

Strategy: validation

Validate before calling

return nil unless params[:course].present? && params[:copied_at].present?
Lti::Pns::LtiContextCopyNoticeBuilder.new(params)

Try / catch

begin
  Lti::Pns::LtiContextCopyNoticeBuilder.new(course:, copied_at: copied_at)
rescue ArgumentError => e
  Rails.logger.warn("context copy notice skipped: #{e.message}")
end

Prevention

When it happens

Trigger: Calling Lti::Pns::LtiContextCopyNoticeBuilder.new(course: course) without :copied_at, or passing nil — e.g. when the copy completion timestamp wasn't recorded before the notice was built.

Common situations: Job handlers that pass raw job arguments missing the timestamp; timezone/serialization code that turned the timestamp into nil; newer callers added before the copied_at requirement existed.

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

Appendix: source

Thrown at app/models/lti/pns/lti_context_copy_notice_builder.rb:27

# the terms of the GNU Affero General Public License as published by the Free
# Software Foundation, version 3 of the License.
#
# Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
# details.
#
# You should have received a copy of the GNU Affero General Public License along
# with this program. If not, see <http://www.gnu.org/licenses/>.

module Lti
  module Pns
    class LtiContextCopyNoticeBuilder < NoticeBuilder
      attr_reader :params

      def initialize(params = {})
        raise ArgumentError, "Missing required parameter: course" unless params[:course]
        raise ArgumentError, "Missing required parameter: copied_at" unless params[:copied_at]

        @params = params
        super()
      end

      def notice_type
        Lti::Pns::NoticeTypes::CONTEXT_COPY
      end

      def custom_instructure_claims(_tool)
        {}
      end

      def custom_ims_claims(_tool)
        course = params[:course]

        context = {
          id: Lti::V1p1::Asset.opaque_identifier_for(course),

View on GitHub (pinned to 1c9f0bb801)