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

  1. Check response.code for non-200 before parsing the body
  2. Compare the returned Content-Type against the formats requested when enqueuing the query
  3. Inspect response.body to identify the actual (likely HTML error) payload
  4. 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

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


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)