instructure/canvas-lms · error · Common::InvalidResultError
Result format is invalid: #
Error message
Result format is invalid: #{content_type} What it means
PageViews::FetchBatchResultService#determine_result_format raises Common::InvalidResultError when the response Content-Type (after stripping parameters like charset) is not a key in Common::CONTENT_TYPE_MAPPINGS. The service only knows how to handle the mapped formats (e.g. CSV/JSON), so anything else is rejected.
Solutions
- Check response.code for non-200 before parsing the body
- Compare the returned Content-Type against the formats requested when enqueuing the query
- Inspect response.body to identify the actual (likely HTML error) payload
- Update/add the mapping in Common::CONTENT_TYPE_MAPPINGS if a new legitimate format was introduced
Example fix
// before
raise "bad format" # vague; inspect first
// after
unless response.code == '200'
raise "page views result fetch failed: #{response.code} #{response.body[0, 200]}"
end
format = service.call(response) Defensive patterns
Strategy: try-catch
Validate before calling
ctype = response.header['Content-Type'].to_s.split(';').first.to_s.strip
raise "unexpected content type: #{ctype}" unless PageViews::Common::CONTENT_TYPE_MAPPINGS.key?(ctype) Try / catch
begin
result = service.call(response)
rescue PageViews::Common::InvalidResultError => e
if e.message.start_with?('Result format is invalid')
Rails.logger.error("page views returned unsupported type: #{e.message} body=#{response.body[0, 200]}")
end
raise
end Prevention
- Check for HTML error pages (text/html) before parsing
- Request only formats present in CONTENT_TYPE_MAPPINGS
- Handle auth failures that return non-data content types
- Keep CONTENT_TYPE_MAPPINGS in sync with API changes
When it happens
Trigger: Server responds with text/html (error page), application/json when only CSV is expected (or vice versa), text/plain, or a custom type not registered in CONTENT_TYPE_MAPPINGS.
Common situations: Auth failure returning an HTML login/error page; version drift where the API added a new format the client doesn't map; requesting a format the endpoint no longer supports; hitting an HTML 404/500 page.
Related errors
- Missing Content-Type header in response.
- Missing Content-Type header in response.
- Content-Type must be 'application/xml'
- Result format is invalid: #
- Unable to determine filename from Content-Disposition header
AI-assisted analysis of instructure/canvas-lms@1c9f0bb801 (2026-09-15).
Data as JSON: /api/errors/56778e9c9b2c92bb.
Report an issue: GitHub.
Appendix: source
Thrown at app/services/page_views/fetch_batch_result_service.rb:43
uri,
request_headers
) do |response|
handle_generic_errors(response) unless response.code.to_i == 200
response.decode_content = false # Prevent automatic decompression
format = determine_result_format(response)
filename = determine_filename(response)
return Common::DownloadableResult.new(format:, filename:, content: response.body)
end
end
private
def determine_result_format(response)
raise InvalidResultError, "Missing Content-Type header in response." unless response.header["Content-Type"]
# strip any parameters (encoding for example) from the Content-Type
content_type = response.header["Content-Type"].split(";").first.strip
raise Common::InvalidResultError, "Result format is invalid: #{content_type}" unless Common::CONTENT_TYPE_MAPPINGS[content_type]
Common::CONTENT_TYPE_MAPPINGS[content_type]
end
def determine_filename(response)
content_disposition = response.header["Content-Disposition"]
if content_disposition && content_disposition =~ /filename="?([^";]+)"?/
Regexp.last_match(1)
else
raise Common::InvalidResultError, "Unable to determine filename from Content-Disposition header"
end
end
end
end
View on GitHub (pinned to 1c9f0bb801)