instructure/canvas-lms · error · Lti::IMS::AdvantageErrors::InvalidResourceLinkIdFilter
Tool does not have access to rlid or rlid does not exist
Error message
Tool does not have access to rlid or rlid does not exist
What it means
Guard in MembershipsProvider#resource_link: for an NRPS request with an rlid, either the tool lacks access to that Lti::ResourceLink or the rlid doesn't resolve — the resource link's current external tool doesn't match the requesting tool (by id or by same registration/dev key in the root account). Raised as InvalidResourceLinkIdFilter.
Solutions
- Ensure the LTI launch/NRPS call uses the same tool (or registration dev key) that owns the resource link
- Verify the rlid value matches an existing Lti::ResourceLink uuid
Defensive patterns
Strategy: validation
When it happens
Trigger: Thrown at app/controllers/lti/ims/providers/memberships_provider.rb:117 when the library encounters an invalid state.
Common situations: See trigger scenarios.
AI-assisted analysis of instructure/canvas-lms@1c9f0bb801 (2026-09-15).
Data as JSON: /api/errors/33298ea80c8f590e.
Report an issue: GitHub.
Appendix: source
Thrown at app/controllers/lti/ims/providers/memberships_provider.rb:117
return nil unless rlid?
return @resource_link if defined?(@resource_link)
rl = Lti::ResourceLink.find_by(resource_link_uuid: rlid)
if rl.present?
# context here is a decorated context, we want the original
current_tool = rl.current_external_tool(Lti::IMS::Providers::MembershipsProvider.unwrap(context))
# Allow access if IDs match exactly, or if both are from the same LTI 1.3
# registration (same developer key) within the same root account. The latter
# handles cases where the same registration is installed at multiple context
# levels (e.g., course and account), and a resource link created by one
# installation is accessed by another. The root_account_id guard prevents
# a global/inherited developer key from granting cross-root-account access.
unless current_tool &&
(current_tool.id == tool.id ||
(tool.use_1_3? && tool.developer_key_id.present? &&
current_tool.developer_key_id == tool.developer_key_id &&
current_tool.root_account_id == tool.root_account_id))
raise Lti::IMS::AdvantageErrors::InvalidResourceLinkIdFilter.new(
"Tool does not have access to rlid #{rlid}",
api_message: "Tool does not have access to rlid or rlid does not exist"
)
end
end
@resource_link = rl
end
def content_tag
return nil unless resource_link
ContentTag.find_by(associated_asset: resource_link)
end
def role
controller.params[:role]
endView on GitHub (pinned to 1c9f0bb801)