instructure/canvas-lms · warning
Couldn't send LTI AGS grade progress metric
Error message
Couldn't send LTI AGS grade progress metric
What it means
After creating/updating scores, ScoresController best-effort reports grading progress to the LTI tool's data collection endpoint via CanvasHttp.put. Any exception in that telemetry call (network failure, bad endpoint, timeout) is rescued and only logged as this warning — the main score operation is unaffected.
Solutions
- Check network egress from Canvas to the tool domain (curl the endpoint from the web container)
- Verify the tool's AGS data_collection_endpoint configuration is a valid, reachable URL
- Confirm CanvasHttp timeout and proxy settings
- Ignore if intentional — grade sync succeeded; only the progress metric is lost
Example fix
// before
CanvasHttp.put(data_collection_endpoint, {}, body: put_body.to_json, content_type: 'application/json')
// after
if data_collection_endpoint.present?
CanvasHttp.put(data_collection_endpoint, {}, body: put_body.to_json, content_type: 'application/json')
end Defensive patterns
Strategy: try-catch
Validate before calling
return unless data_collection_endpoint.present? && data_collection_endpoint.start_with?('http') Type guard
def valid_endpoint?(url) uri = URI.parse(url) rescue nil uri.is_a?(URI::HTTP) || uri.is_a?(URI::HTTPS) end
Try / catch
begin
CanvasHttp.put(endpoint, {}, body: body.to_json, content_type: 'application/json')
rescue StandardError => e
Rails.logger.warn("Couldn't send LTI AGS grade progress metric: #{e.class}: #{e.message}")
end Prevention
- Validate data_collection_endpoint at tool configuration time
- Monitor CanvasHttp timeouts/egress from the Canvas cluster
- Treat this metric as best-effort; keep the main score flow independent of it
When it happens
Trigger: CanvasHttp.put to data_collection_endpoint raises: DNS/connection failure to the tool domain, HTTP timeout, invalid/unreachable endpoint URL, or body serialization failure.
Common situations: Tool host down or firewalled; misconfigured AGS data_collection_endpoint on the LineItem/tool; CanvasHttp timeouts under load; egress blocked in the Canvas cluster.
Understand the failure class
Background: 'Something went wrong' / 'Request failed (500)' / 'HTTP error! status: 404' — what failed HTTP requests actually mean and how to find the real cause — this error's family across 28 libraries.
Related errors
- could not retrieve configuration, the server response timed…
- Fetching data from #
- Unable to fetch export data from #
- Unable to start import for external tool #
- Content-Type must be 'application/xml'
AI-assisted analysis of instructure/canvas-lms@1c9f0bb801 (2026-09-15).
Data as JSON: /api/errors/b94d9a605c8ae246.
Report an issue: GitHub.
Appendix: source
Thrown at app/controllers/lti/ims/scores_controller.rb:105
MIME_TYPE = "application/vnd.ims.lis.v1.score+json"
def report_grade_progress_metric
dynamic_settings_tree = DynamicSettings.find(tree: :private)
if dynamic_settings_tree["frontend_data_collection_endpoint"]
data_collection_endpoint = dynamic_settings_tree["frontend_data_collection_endpoint"]
put_body = [{
id: SecureRandom.uuid,
type: "ags_grade_progress",
account_id: @domain_root_account.id.to_s,
account_name: @domain_root_account.name,
tool_domain: tool.domain,
grading_progress: params[:gradingProgress]
}]
CanvasHttp.put(data_collection_endpoint, {}, body: put_body.to_json, content_type: "application/json")
end
rescue
Rails.logger.warn("Couldn't send LTI AGS grade progress metric")
end
# @API Create a Score
#
# Create a new Result from the score params. If this is for the first created line_item for a
# resourceLinkId, or it is a line item that is not attached to a resourceLinkId, then a submission
# record will be created for the associated assignment when gradingProgress is set to
# FullyGraded or PendingManual.
#
# The submission score will also be updated when a score object is sent with either of those
# two values for gradingProgress. If a score object is sent with either of FullyGraded or
# PendingManual as the value for gradingProgress and scoreGiven is missing, the assignment
# will not be graded. This also supposes the line_item meets the condition to create a submission.
#
# A submission comment with an unknown author will be created when the comment value is included.
# This also supposes the line_item meets the condition to create a submission.
#
# It is also possible to submit a file along with this score, which will attach the file to theView on GitHub (pinned to 1c9f0bb801)