instructure/canvas-lms · error · Lti::PlatformNotificationService::InvalidNoticeHandler
e.message
Error message
e.message
What it means
Lti::PlatformNotificationService.subscribe_tool_for_notice builds an Lti::NoticeHandler and calls handler.validate!. If ActiveRecord validation fails (RecordInvalid), the record's validation message is re-raised as Lti::PlatformNotificationService::InvalidNoticeHandler. The bracketed text is the raise expression; the real message is the model's 'Validation failed: ...' string.
Solutions
- Read the raised InvalidNoticeHandler message for the exact failing validation on Lti::NoticeHandler.
- Check for an existing handler for the same tool and notice_type and unsubscribe/update instead of creating a duplicate.
- Ensure tool is a persisted Lti::Tool with a valid id and max_batch_size is a positive integer.
- Fix the payload so it satisfies NoticeHandler model validations, then retry subscribe_tool_for_notice.
Example fix
# before Lti::PlatformNotificationService.subscribe_tool_for_notice(tool:, notice_type: 'hello_world', max_batch_size: 0) # after Lti::PlatformNotificationService.subscribe_tool_for_notice(tool:, notice_type: Lti::Pns::NoticeTypes::HELLO_WORLD, max_batch_size: 1)
Defensive patterns
Strategy: validation
Validate before calling
existing = Lti::NoticeHandler.find_by(tool:, notice_type:) raise 'duplicate subscription' if existing raise ArgumentError, 'max_batch_size must be positive' if max_batch_size && max_batch_size < 1
Try / catch
begin
Lti::PlatformNotificationService.subscribe_tool_for_notice(tool:, notice_type:, max_batch_size:)
rescue Lti::PlatformNotificationService::InvalidNoticeHandler => e
render json: { error: e.message }, status: :unprocessable_entity
end Prevention
- Check for an existing handler for (tool, notice_type) before subscribing
- Ensure the tool is persisted with a valid id
- Validate max_batch_size is a positive integer before the call
- Keep notice_type values sourced from Lti::Pns::NoticeTypes constants
When it happens
Trigger: Subscribing a tool to a notice type where the Lti::NoticeHandler fails model validation — duplicate handler for (tool, notice_type), blank tool or notice_type, invalid max_batch_size, or other NoticeHandler model constraints.
Common situations: Installing the same LTI 1.3 platform notification subscription twice; tool passed without being persisted/having an id; max_batch_size set below 1 or to a non-integer; notice_type typo not caught by the earlier model check.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- Missing required asset parameter #
- Missing required parameter: copied_at
- Missing required parameter: course
- Missing required parameter: #
- Validation failed: Notice type unknown, must be one of
AI-assisted analysis of instructure/canvas-lms@1c9f0bb801 (2026-09-15).
Data as JSON: /api/errors/ece17b1094eb97f6.
Report an issue: GitHub.
Appendix: source
Thrown at app/services/lti/platform_notification_service.rb:38
module Lti
module PlatformNotificationService
module_function
class InvalidNoticeHandler < StandardError; end
def subscribe_tool_for_notice(tool:, notice_type:, handler_url:, max_batch_size:)
validate_notice_type!(notice_type)
handler = tool.lti_notice_handlers.new(
notice_type:,
url: handler_url,
account: tool.related_account,
max_batch_size:
)
begin
handler.validate!
rescue ActiveRecord::RecordInvalid => e
raise InvalidNoticeHandler, e.message
end
destroy_notice_handlers(tool:, notice_type:)
handler.save!
if notice_type == Lti::Pns::NoticeTypes::HELLO_WORLD
send_notices(notice_handler: handler, builders: [Lti::Pns::LtiHelloWorldNoticeBuilder.new])
end
handler_api_json(handler:)
end
def unsubscribe_tool_for_notice(tool:, notice_type:)
validate_notice_type!(notice_type)
destroy_notice_handlers(tool:, notice_type:)
empty_api_json(notice_type:)
end
# @return [Array<Hash>] list of notice handlers for the tool in api formatView on GitHub (pinned to 1c9f0bb801)