instructure/canvas-lms · error · OtherError
Invalid upload type
Error message
Invalid upload type
What it means
After validating the item type, do_import checks that uploadType is exactly "zipPackage". The Respondus SOAP import protocol only supports zipped IMS/QTI packages; any other upload format is rejected with OtherError.
Solutions
- Send uploadType as exactly "zipPackage" (case-sensitive)
- Zip the QTI/IMS package before uploading and confirm the client sends it as a zip package
- Check the Respondus client server-type profile is set to Canvas
Example fix
// before
client.publish("quiz", xmlData, "qtiPackage")
// after
client.publish("quiz", zipData, "zipPackage") Defensive patterns
Strategy: validation
Validate before calling
if (uploadType !== "zipPackage") throw new Error("uploadType must be exactly 'zipPackage'"); Try / catch
begin servant.publishServerItem(session, itemType, uploadType, ...) rescue RespondusApi::OtherError zip the package and resend end
Prevention
- Zip QTI/IMS content before upload
- Use case-sensitive string literal 'zipPackage'
- Configure the client for the Canvas server profile
When it happens
Trigger: Calling publishServerItem/replaceServerItem with uploadType set to anything other than "zipPackage" (e.g. "file", "qtiPackage", wrong casing like "ZipPackage").
Common situations: Client configured for a non-Canvas server type that allows other upload formats; hand-rolled SOAP clients passing raw XML or unzipped QTI; version mismatch between client and Canvas plugin expectations.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
AI-assisted analysis of instructure/canvas-lms@1c9f0bb801 (2026-09-15).
Data as JSON: /api/errors/d47320928c3a8dcd.
Report an issue: GitHub.
Appendix: source
Thrown at gems/plugins/respondus_soap_endpoint/lib/respondus_soap_endpoint/urn_RespondusAPIServant.rb:550
end
ASSET_TYPES = {
"quiz" => "Quizzes::Quiz",
"qdb" => "AssessmentQuestionBank",
}.freeze
ATTACHMENT_FOLDER_NAME = "imported qti files"
def do_import(item, itemType, uploadType, _fileName, fileData)
if fileData == "\x0" && session["pending_migration_id"]
return poll_for_completion
end
unless %w[quiz qdb].include?(itemType)
raise OtherError, "Invalid item type"
end
if uploadType != "zipPackage"
raise OtherError, "Invalid upload type"
end
selection_state = session["selection_state"] || []
course = Course.where(id: selection_state.first).first
raise(OtherError, "Item type incompatible with selection state") unless course
# Make sure that the image import folder is hidden by default
Folder.assert_path(ATTACHMENT_FOLDER_NAME, course) do |folder|
folder.hidden = true
end
settings = {
migration_type: "qti_converter",
apply_respondus_settings_file: (itemType != "qdb"),
skip_import_notification: true,
files_import_allow_rename: true,
files_import_root_path: ATTACHMENT_FOLDER_NAME,
flavor: Qti::Flavors::RESPONDUSView on GitHub (pinned to 1c9f0bb801)