instructure/canvas-lms · error · InvalidResultError
Missing Content-Type header in response.
Error message
Missing Content-Type header in response.
What it means
PageViews::FetchBatchResultService#determine_result_format raises InvalidResultError when the HTTP response has no Content-Type header. The service maps Content-Type to a result format via Common::CONTENT_TYPE_MAPPINGS and cannot decide how to process/deliver the body without it.
Solutions
- Log and inspect response.header and response.code before processing to see what the server actually returned
- Verify the result URL is the one returned by the async query status endpoint
- Check proxy/load-balancer config for header stripping (Content-Type)
- Retry the fetch; transient gateway errors often lack proper headers
Example fix
// before
format = service.call(response) # raises if header missing
// after
unless response.header['Content-Type']
raise "unexpected response (code=#{response.code}): #{response.body[0, 200]}"
end
format = service.call(response) Defensive patterns
Strategy: try-catch
Validate before calling
raise 'missing Content-Type from page views API' if response.header['Content-Type'].blank?
Try / catch
begin
result = PageViews::FetchBatchResultService.new(config).call(response)
rescue PageViews::InvalidResultError => e
Rails.logger.error("bad page views response: #{e.message} (code=#{response.code})")
raise
end Prevention
- Check response.code is 200 before processing the body
- Log response headers on unexpected responses for debugging
- Watch for proxies stripping Content-Type
- Retry transient gateway failures
When it happens
Trigger: The batch result endpoint returned a response with a missing/blank Content-Type header — typically an error page, redirect, or misconfigured proxy/gateway response passed to call.
Common situations: Reverse proxy stripping headers; the remote service returning an empty error response; hitting the wrong URL (e.g. HTML 404 page without proper content type); network middleware interference in dev.
Related errors
- Missing Content-Type header in response.
- Result format is invalid: #
- 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/785cb29e4441d0a3.
Report an issue: GitHub.
Appendix: source
Thrown at app/services/page_views/fetch_batch_result_service.rb:39
class FetchBatchResultService < PageViews::ServiceBase
def call(query_id)
uri = @configuration.uri.merge("/api/v5/pageviews/batch-query/#{query_id}/results")
get_with_clean_redirect(
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
endView on GitHub (pinned to 1c9f0bb801)