instructure/canvas-lms · error · Canvadocs::Error

TODO: support raw files

Error message

TODO: support raw files

What it means

Canvadocs#upload accepts either a URL string or a File object, but the File branch is unimplemented: it immediately raises Canvadocs::Error "TODO: support raw files" before any API call. Only URL-based submissions are supported by this client method.

Solutions

  1. Pass a URL string instead of a File — e.g. the attachment's public download or a pre-signed S3 URL — via upload(url, extra_params).
  2. Upload the raw bytes to S3 (or other host) yourself and give Canvadocs the resulting URL.
  3. If you need raw file support, patch upload to use a multipart POST, or upgrade to a canvadocs client version that supports it.

Example fix

// before
canvadocs.upload(File.open(path))
// after
url = Attachment.new.tap { |a| a.uploaded_data = file }.public_download_url
canvadocs.upload(url)
Defensive patterns

Strategy: validation

Validate before calling

# ruby
obj.is_a?(String) or raise ArgumentError, "canvadocs upload requires a URL, not a File"

Try / catch

begin
  canvadocs.upload(obj)
rescue Canvadocs::Error => e
  raise "use a URL: #{e.message}" if e.message.include?("raw files")
end

Prevention

When it happens

Trigger: Calling canvadocs_api.upload(file_object) with an actual File/IO object; the raise happens inside the obj.is_a?(File) branch.

Common situations: Developers attaching an uploaded attachment's IO stream directly instead of its authenticated public/preview URL; writing custom preview integrations that read from disk.

Related errors


AI-assisted analysis of instructure/canvas-lms@1c9f0bb801 (2026-09-15). Data as JSON: /api/errors/c9a4f2e9c74f2e3b. Report an issue: GitHub.

Appendix: source

Thrown at lib/canvadocs.rb:69

    end

    # -- Documents --

    # Public: Create a document with the file at the given url.
    #
    # obj - a url string
    # params - other post params
    #
    # Examples
    #
    #   upload("http://www.example.com/test.doc")
    #   # => { "id": 1234, "status": "queued" }
    #
    # Returns a hash containing the document's id and status
    def upload(obj, extra_params = {})
      params = if obj.is_a?(File)
                 { file: obj }.merge(extra_params)
                 raise Canvadocs::Error, "TODO: support raw files"
               else
                 { url: obj.to_s }.merge(extra_params)
               end

      raw_body = api_call(:post, "documents", params)
      JSON.parse(raw_body)
    end

    # Public: Delete a document.
    #
    # id - a single document id to delete
    #
    def delete(id)
      api_call(:delete, "documents/#{id}")
    end

    # -- Sessions --

View on GitHub (pinned to 1c9f0bb801)